Update DNS records on Client Connect in your OpenVPN Server

October 22, 2023

In this post I will explain you how to update your DNS server when a client connects to your OpenVPN server, in the example I will be using PowerDNS as my authoritative name server, which runs on the same machine. However you can easily customize the script to your configured environment. This has been tested on Ubuntu 22.04.

1. Create the Client Connect Hook script

We will create a script that gets called by the OpenVPN server when a client connects. We will use the Common Name of the client as the name for the A record.

sudo nano /etc/openvpn/client-connect.sh
#!/bin/bash
# https://MrWaggel.be

# For debugging in logs
echo "Client-Connect called for $common_name"

# Use the common name as the record name.
record=$(echo "$common_name" | tr '_' '-' |  tr ' ' '-')

# Remove old records with the same name
pdnsutil delete-rrset example.com $record A

# Update the record in PowerDNS using pdnsutil
pdnsutil add-record example.com $record A 60 $ifconfig_pool_remote_ip

The script is quite short as you can see, when the OpenVPN server runs a script it passes environment variables related to the client1 in question. The script works as following;

  1. Echo something in case we need to debug, so you can search for this line.
  2. First we sanitize the Common Name by replacing spaces and underscores with '-'. This example it is quite basic and does not take in account special characters or different alphabets, refer to the list of valid characters in DNS names2, and adjust to your own needs.
  3. Removing any previous A records for the record name to prevent having multiple A records with different IP addresses, it results in a no-op when the record is not found, so the return code is 0.
  4. Create a new A record for the client, where the value is the Virtual IP address it gets assigned $ifconfig_pool_remote_ip, with a TTL of 60 seconds.

Good to know, if your script does not exit with code 0, the client will not be allowed to connect.

Make sure the script is executable, and only by root, else other users on the machine would be able to change DNS records.

sudo chmod 700 /etc/openvpn/client-connect.sh

2. Edit the server.conf

Now it is time to edit your OpenVPN server configuration. The default location for this config file is:

sudo nano /etc/openvpn/server.conf

Change or add the following values in your config file.

user root
script-security 2
client-connect /etc/openvpn/client-connect.sh
  • user: for simplicity we use root here, however if you want more security you can change it your environment, but make sure the ownership of the script is adjusted as well, and that the user can execute changes towards your DNS servers.
  • script-security: required if you want OpenVPN to execute scripts. You can set it to 3 if you need to read out the password that the client provides when it connects to do some custom authentication handling.
  • client-connect: the absolute path to the script that gets called when the client connects.

3. Restart the server

Time to restart the server and test the script, for systemd users;

sudo systemctl restart openvpn-server

# Follow logs for testing and debugging purposes
journalctl -u openvpn@server.service -f

Connect a client to your server and check the logs for any errors or messages.

Read also

OpenVPN client force DNS servers in Linux
OpenVPN client pass login credentials and passphrase in Linux
InstantFileWebServer release v0.1
The Difference Between a Virtual Private Server and a Dedicated Server
Golang serving resume able file downloads with net/http
The National Sport of Mozambique: Capoeira
Comments
References
1
openvpn

https://build.openvpn.net/man/openvpn-2.5/openvpn.8.html#environmental-variables

cached copy
2
Name computers, domains, sites, and OUs - Windows Server | Microsoft Learn

https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/naming-conventions-for-computer-domain-site-ou#dns-host-names

cached copy
Tags