How to set up an OpenVPN tunnel with Google Authenticator
--
After creating an OpenVPN tunnel, we want to make the connection more secure using a One-Time-Password (OTP). To do this, we use, for instance, Google Authenticator.
Setup the OpenVPN tunnel
You can follow this tutorial to set up the OpenVPN tunnel between the client and the server.
Download the Google Authenticator App
You can download Google Authenticator on Play Store or App Store.
Install the libraries
On the server, you need to install the following libraries.
sudo apt-get install -y libqrencode4 libpam-google-authenticator
Configure the server
You need to create a new user we called gauth.
cd /etc/openvpn/
addgroup gauth
useradd -g gauth gauth
sudo google-authenticator
mkdir google-authenticator
chown gauth:gauth google-authenticator
chmod 0700 google-authenticator
Then you need to edit the server.conf
.
nano server.conf
Adding the following line
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so \“login login USERNAME password PASSWORD pin OTP\”
Your server.conf
file should look like this.
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so \"login login USERNAME password PASSWORD pin OTP\"
local 192.168.172.70
port 1195 # DIFFERENT FROM TUN1
proto udp
dev tun
ca /etc/pki/CA/certs/ca.crt
cert /etc/pki/CA/certs/tun0-server.crt
key /etc/pki/CA/private/tun0-server.key
dh /etc/pki/CA/openvpn/dh2048.pem
server 10.7.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push \"route 10.8.0.0 255.255.255.0\"
keepalive 10 120
tls-auth /etc/pki/CA/private/ta.key 0
cipher AES-256-CBC
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
script-security 2
tls-verify /etc/pki/OCSP_check.sh
verb 3
explicit-exit-notify 1
Now edit the nano login
file.
nano /etc/pam.d/login
Add the following line at the beginning (replacing {USER} with the username of the session account).
auth required pam_google_authenticator.so secret=/etc/openvpn/google-authenticator/<USER> forward_pass
Your login
file should look like this.
auth required pam_google_authenticator.so secret=/etc/openvpn/google-authenticator/<USER> forward_pass
...
Then for generating the QRCode, you need to run the following command (replacing {USER} with the username of the session account).
su -c "google-authenticator -t -d -r3 -R30 -f -l 'OpenVPN Server' -s /etc/openvpn/google-authenticator/{USER}" - gauth
Now the console should output a QRCode with the following message.
Your new secret key is: 6DGZQVG5E6SSWCLXKYCKXHJHPA
Enter code from app (-1 to skip): 962663
Code confirmed
Your emergency scratch codes are:
38250790
17829309
86725593
79778279
47995335
By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) y
Scan the QRCode or insert the code manually with the Google Authenticator App.
Configure the client
Edit the client.conf
.
cd /etc/openvpn/
nano client.conf
Adding the following line
auth-user-pass
Your client.conf
file should look like this.
auth-user-pass
client
dev tun
proto udp
remote 192.168.172.70 1195
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/pki/CA/certs/ca.crt
cert /etc/pki/CA/certs/tun0-client.crt
key /etc/pki/CA/private/tun0-client.key
tls-auth /etc/pki/CA/private/ta.key 1
cipher AES-256-CBC
verb 3
Restart all the services on each side and when the client.
Then the client will prompt a message asking for a username, a password, and the private key password.
When the client asks for the password, you need to concatenate the user password with the OTP.
If the password is example-pass
and the OTP is the 344938
, you should enter:
example-pass344938
You can now ping your server!