Jump to content

OpenVPN:User Management: Difference between revisions

From jb-vpn.uk Wiki
Content removed - troubleshooting guide: OpenVPN User Management (12 sections)
Major update - troubleshooting guide: OpenVPN User Management (58 sections)
 
Line 1: Line 1:
= OpenVPN User Management =
This document covers managing OpenVPN users (clients) including adding, removing, and managing client certificates.
This document covers managing OpenVPN users (clients) including adding, removing, and managing client certificates.


Line 28: Line 26:


<pre class="lang-bash">
<pre class="lang-bash">
= Run the installer script =
==== Run the installer script ====
bash /root/openvpn-install.sh
bash /root/openvpn-install.sh


= Select option to add a new client =
== Select option to add a new client ==
= Follow the prompts to enter the client name =
== Follow the prompts to enter the client name ==
= The script will automatically: =
== The script will automatically: ==
=   - Generate the client certificate =
== - Generate the client certificate ==
=   - Create the .ovpn configuration file =
== - Create the .ovpn configuration file ==
=   - Place it in /root/ =
== - Place it in /root/ ==
</pre>
</pre>


Line 43: Line 41:
For manual certificate creation:
For manual certificate creation:


= '''Navigate to Easy-RSA directory''': =
==== '''Navigate to Easy-RSA directory''': ====
   <pre class="lang-bash">
   <pre class="lang-bash">
   cd /etc/openvpn/server/easy-rsa/
   cd /etc/openvpn/server/easy-rsa/
</pre>
</pre>


= '''Generate client certificate and key''': =
== '''Generate client certificate and key''': ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   ./easyrsa build-client-full clientname nopass
   ./easyrsa build-client-full clientname nopass
Line 57: Line 55:
   The <code>nopass</code> option creates a certificate without a password. Remove it if you want password protection.
   The <code>nopass</code> option creates a certificate without a password. Remove it if you want password protection.


= '''Create client configuration file''': =
== '''Create client configuration file''': ==
    
    
   You'll need to create a <code>.ovpn</code> file that combines:
   You'll need to create a <code>.ovpn</code> file that combines:
Line 78: Line 76:
   Then extract and replace the certificate sections:
   Then extract and replace the certificate sections:
   <pre class="lang-bash">
   <pre class="lang-bash">
  # Extract client certificate from Easy-RSA
=== Extract client certificate from Easy-RSA ===
   cat /etc/openvpn/server/easy-rsa/pki/issued/clientname.crt
   cat /etc/openvpn/server/easy-rsa/pki/issued/clientname.crt
    
    
  # Extract client key
=== Extract client key ===
   cat /etc/openvpn/server/easy-rsa/pki/private/clientname.key
   cat /etc/openvpn/server/easy-rsa/pki/private/clientname.key
    
    
  # Replace the <cert> and <key> sections in the .ovpn file
=== Replace the <cert> and <key> sections in the .ovpn file ===
</pre>
</pre>


= '''Verify the configuration''': =
== '''Verify the configuration''': ==
   <pre class="lang-bash">
   <pre class="lang-bash">
  # Test the .ovpn file syntax
=== Test the .ovpn file syntax ===
   openvpn --config /root/newclient.ovpn --test-crypto
   openvpn --config /root/newclient.ovpn --test-crypto
</pre>
</pre>
Line 99: Line 97:
<pre class="lang-bash">
<pre class="lang-bash">
#!/bin/bash
#!/bin/bash
= /root/create-openvpn-client.sh =
== /root/create-openvpn-client.sh ==


CLIENT_NAME=$1
CLIENT_NAME=$1
Line 110: Line 108:
cd /etc/openvpn/server/easy-rsa/
cd /etc/openvpn/server/easy-rsa/


= Generate client certificate =
== Generate client certificate ==
./easyrsa build-client-full "$CLIENT_NAME" nopass
./easyrsa build-client-full "$CLIENT_NAME" nopass


= Create .ovpn file =
== Create .ovpn file ==
CLIENT_DIR="/root"
CLIENT_DIR="/root"
OVPN_FILE="$CLIENT_DIR/$CLIENT_NAME.ovpn"
OVPN_FILE="$CLIENT_DIR/$CLIENT_NAME.ovpn"


= Start with common client configuration =
== Start with common client configuration ==
cat > "$OVPN_FILE" << EOF
cat > "$OVPN_FILE" << EOF
client
client
Line 133: Line 131:
EOF
EOF


= Add CA certificate =
== Add CA certificate ==
echo "<ca>" >> "$OVPN_FILE"
echo "<ca>" >> "$OVPN_FILE"
cat /etc/openvpn/server/ca.crt >> "$OVPN_FILE"
cat /etc/openvpn/server/ca.crt >> "$OVPN_FILE"
echo "</ca>" >> "$OVPN_FILE"
echo "</ca>" >> "$OVPN_FILE"


= Add client certificate =
== Add client certificate ==
echo "<cert>" >> "$OVPN_FILE"
echo "<cert>" >> "$OVPN_FILE"
cat "/etc/openvpn/server/easy-rsa/pki/issued/$CLIENT_NAME.crt" >> "$OVPN_FILE"
cat "/etc/openvpn/server/easy-rsa/pki/issued/$CLIENT_NAME.crt" >> "$OVPN_FILE"
echo "</cert>" >> "$OVPN_FILE"
echo "</cert>" >> "$OVPN_FILE"


= Add client key =
== Add client key ==
echo "<key>" >> "$OVPN_FILE"
echo "<key>" >> "$OVPN_FILE"
cat "/etc/openvpn/server/easy-rsa/pki/private/$CLIENT_NAME.key" >> "$OVPN_FILE"
cat "/etc/openvpn/server/easy-rsa/pki/private/$CLIENT_NAME.key" >> "$OVPN_FILE"
echo "</key>" >> "$OVPN_FILE"
echo "</key>" >> "$OVPN_FILE"


= Add TLS-Crypt key =
== Add TLS-Crypt key ==
echo "<tls-crypt>" >> "$OVPN_FILE"
echo "<tls-crypt>" >> "$OVPN_FILE"
cat /etc/openvpn/server/tc.key >> "$OVPN_FILE"
cat /etc/openvpn/server/tc.key >> "$OVPN_FILE"
Line 171: Line 169:
To assign a static IP address to a client:
To assign a static IP address to a client:


= '''Create a CCD file''' in <code>/etc/openvpn/ccd/</code>: =
=== '''Create a CCD file''' in <code>/etc/openvpn/ccd/</code>: ===
   <pre class="lang-bash">
   <pre class="lang-bash">
   sudo nano /etc/openvpn/ccd/clientname
   sudo nano /etc/openvpn/ccd/clientname
</pre>
</pre>


= '''Add IP assignment''': =
== '''Add IP assignment''': ==
   <pre>
   <pre>
   ifconfig-push 10.8.0.X 255.255.255.0
   ifconfig-push 10.8.0.X 255.255.255.0
Line 183: Line 181:
   Replace <code>X</code> with the desired IP (e.g., <code>10.8.0.10</code>).
   Replace <code>X</code> with the desired IP (e.g., <code>10.8.0.10</code>).


= '''Set proper permissions''': =
== '''Set proper permissions''': ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   sudo chown nobody:nogroup /etc/openvpn/ccd/clientname
   sudo chown nobody:nogroup /etc/openvpn/ccd/clientname
Line 189: Line 187:
</pre>
</pre>


= '''Restart OpenVPN''' (if needed): =
== '''Restart OpenVPN''' (if needed): ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   sudo systemctl restart openvpn
   sudo systemctl restart openvpn
Line 204: Line 202:


<pre class="lang-bash">
<pre class="lang-bash">
= View IP persistence file (shows last assigned IPs) =
=== View IP persistence file (shows last assigned IPs) ===
cat /etc/openvpn/server/ipp.txt
cat /etc/openvpn/server/ipp.txt


= Check active connections via system logs =
== Check active connections via system logs ==
journalctl -u openvpn | grep "Peer Connection Initiated"
journalctl -u openvpn | grep "Peer Connection Initiated"


= Or check the VPN interface =
== Or check the VPN interface ==
ip addr show tun0
ip addr show tun0
</pre>
</pre>
Line 218: Line 216:
When a user should no longer have access:
When a user should no longer have access:


= '''Navigate to Easy-RSA directory''': =
=== '''Navigate to Easy-RSA directory''': ===
   <pre class="lang-bash">
   <pre class="lang-bash">
   cd /etc/openvpn/server/easy-rsa/
   cd /etc/openvpn/server/easy-rsa/
</pre>
</pre>


= '''Revoke the certificate''': =
== '''Revoke the certificate''': ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   ./easyrsa revoke clientname
   ./easyrsa revoke clientname
Line 230: Line 228:
   You'll be prompted to confirm. Type <code>yes</code>.
   You'll be prompted to confirm. Type <code>yes</code>.


= '''Update the Certificate Revocation List (CRL)''': =
== '''Update the Certificate Revocation List (CRL)''': ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   ./easyrsa gen-crl
   ./easyrsa gen-crl
</pre>
</pre>


= '''Copy the updated CRL to the server directory''': =
== '''Copy the updated CRL to the server directory''': ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   cp pki/crl.pem /etc/openvpn/server/crl.pem
   cp pki/crl.pem /etc/openvpn/server/crl.pem
</pre>
</pre>


= '''Restart OpenVPN''' to apply the revocation: =
== '''Restart OpenVPN''' to apply the revocation: ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   systemctl restart openvpn
   systemctl restart openvpn
</pre>
</pre>


= '''Remove client files''' (optional but recommended): =
== '''Remove client files''' (optional but recommended): ==
   <pre class="lang-bash">
   <pre class="lang-bash">
  # Remove .ovpn file
=== Remove .ovpn file ===
   rm /root/clientname.ovpn
   rm /root/clientname.ovpn
    
    
  # Remove CCD file if it exists
=== Remove CCD file if it exists ===
   rm /etc/openvpn/ccd/clientname
   rm /etc/openvpn/ccd/clientname
</pre>
</pre>
Line 258: Line 256:
== Security Best Practices ==
== Security Best Practices ==


= '''Use descriptive client names''': Use names that identify the device/user (e.g., <code>laptop-john</code>, <code>phone-mary</code>, <code>nas-synology</code>) =
=== '''Use descriptive client names''': Use names that identify the device/user (e.g., <code>laptop-john</code>, <code>phone-mary</code>, <code>nas-synology</code>) ===


= '''Regular certificate rotation''': Renew certificates before expiration (typically annually) =
== '''Regular certificate rotation''': Renew certificates before expiration (typically annually) ==


= '''Revoke unused certificates''': Remove access for users who no longer need VPN access =
== '''Revoke unused certificates''': Remove access for users who no longer need VPN access ==


= '''Secure .ovpn file distribution''': Use secure channels (encrypted email, secure file transfer) when sending <code>.ovpn</code> files to clients =
== '''Secure .ovpn file distribution''': Use secure channels (encrypted email, secure file transfer) when sending <code>.ovpn</code> files to clients ==


= '''Limit static IP assignments''': Only assign static IPs when necessary (e.g., for services like the Synology NAS) =
== '''Limit static IP assignments''': Only assign static IPs when necessary (e.g., for services like the Synology NAS) ==


= '''Monitor active connections''': Regularly check who is connected and verify it's expected =
== '''Monitor active connections''': Regularly check who is connected and verify it's expected ==


= '''Keep Easy-RSA secure''': The Easy-RSA directory contains sensitive keys - restrict access: =
== '''Keep Easy-RSA secure''': The Easy-RSA directory contains sensitive keys - restrict access: ==
   <pre class="lang-bash">
   <pre class="lang-bash">
   chmod 700 /etc/openvpn/server/easy-rsa/
   chmod 700 /etc/openvpn/server/easy-rsa/
Line 280: Line 278:


<pre class="lang-bash">
<pre class="lang-bash">
= Backup all certificates and keys =
=== Backup all certificates and keys ===
tar -czf openvpn-users-backup-$(date +%Y%m%d).tar.gz \
tar -czf openvpn-users-backup-$(date +%Y%m%d).tar.gz \
   /etc/openvpn/server/easy-rsa/pki/ \
   /etc/openvpn/server/easy-rsa/pki/ \

Latest revision as of 13:44, 1 January 2026

This document covers managing OpenVPN users (clients) including adding, removing, and managing client certificates.

Overview

[edit]

OpenVPN uses certificate-based authentication. Each user (client) requires:

  • A unique client certificate
  • A client configuration file (.ovpn)
  • Optionally, a static IP assignment via CCD file

Current Users

[edit]

Client configuration files are stored in /root/:

  • josh.ovpn
  • Work_MacBook_Air.ovpn
  • StrawberryNAS.ovpn (Synology NAS with static IP 10.8.0.2)

Adding a New User

[edit]

Method 1: Using the OpenVPN Install Script (Recommended)

[edit]

If you have the openvpn-install.sh script available:

==== Run the installer script ====
bash /root/openvpn-install.sh

== Select option to add a new client ==
== Follow the prompts to enter the client name ==
== The script will automatically: ==
== - Generate the client certificate ==
== - Create the .ovpn configuration file ==
== - Place it in /root/ ==

Method 2: Manual Certificate Creation with Easy-RSA

[edit]

For manual certificate creation:

[edit]
   cd /etc/openvpn/server/easy-rsa/

Generate client certificate and key:

[edit]
   ./easyrsa build-client-full clientname nopass
  Replace clientname with the desired client name (e.g., newuser, laptop-john).
  
  The nopass option creates a certificate without a password. Remove it if you want password protection.

Create client configuration file:

[edit]
  You'll need to create a .ovpn file that combines:
  * Client certificate
  * Client private key
  * CA certificate
  * TLS-Crypt key
  * Connection settings


  Use an existing .ovpn file as a template:
   cp /root/josh.ovpn /root/newclient.ovpn
  Then extract and replace the certificate sections:
=== Extract client certificate from Easy-RSA ===
   cat /etc/openvpn/server/easy-rsa/pki/issued/clientname.crt
   
=== Extract client key ===
   cat /etc/openvpn/server/easy-rsa/pki/private/clientname.key
   
=== Replace the <cert> and <key> sections in the .ovpn file ===

Verify the configuration:

[edit]
=== Test the .ovpn file syntax ===
   openvpn --config /root/newclient.ovpn --test-crypto

Method 3: Using Easy-RSA Helper Script

[edit]

Create a helper script to automate the process:

#!/bin/bash
== /root/create-openvpn-client.sh ==

CLIENT_NAME=$1

if [ -z "$CLIENT_NAME" ]; then
    echo "Usage: $0 <client-name>"
    exit 1
fi

cd /etc/openvpn/server/easy-rsa/

== Generate client certificate ==
./easyrsa build-client-full "$CLIENT_NAME" nopass

== Create .ovpn file ==
CLIENT_DIR="/root"
OVPN_FILE="$CLIENT_DIR/$CLIENT_NAME.ovpn"

== Start with common client configuration ==
cat > "$OVPN_FILE" << EOF
client
dev tun
proto udp
remote 87.106.61.62 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
ignore-unknown-option block-outside-dns
verb 3
EOF

== Add CA certificate ==
echo "<ca>" >> "$OVPN_FILE"
cat /etc/openvpn/server/ca.crt >> "$OVPN_FILE"
echo "</ca>" >> "$OVPN_FILE"

== Add client certificate ==
echo "<cert>" >> "$OVPN_FILE"
cat "/etc/openvpn/server/easy-rsa/pki/issued/$CLIENT_NAME.crt" >> "$OVPN_FILE"
echo "</cert>" >> "$OVPN_FILE"

== Add client key ==
echo "<key>" >> "$OVPN_FILE"
cat "/etc/openvpn/server/easy-rsa/pki/private/$CLIENT_NAME.key" >> "$OVPN_FILE"
echo "</key>" >> "$OVPN_FILE"

== Add TLS-Crypt key ==
echo "<tls-crypt>" >> "$OVPN_FILE"
cat /etc/openvpn/server/tc.key >> "$OVPN_FILE"
echo "</tls-crypt>" >> "$OVPN_FILE"

echo "Client configuration created: $OVPN_FILE"
echo "Send this file securely to the client."

Make it executable:

chmod +x /root/create-openvpn-client.sh

Usage:

/root/create-openvpn-client.sh newclientname

Assigning Static IP Addresses

[edit]

To assign a static IP address to a client:

Create a CCD file in /etc/openvpn/ccd/:

[edit]
   sudo nano /etc/openvpn/ccd/clientname

Add IP assignment:

[edit]
   ifconfig-push 10.8.0.X 255.255.255.0
  Replace X with the desired IP (e.g., 10.8.0.10).

Set proper permissions:

[edit]
   sudo chown nobody:nogroup /etc/openvpn/ccd/clientname
   sudo chmod 600 /etc/openvpn/ccd/clientname

Restart OpenVPN (if needed):

[edit]
   sudo systemctl restart openvpn

Example: The Synology NAS has a CCD file at /etc/openvpn/ccd/StrawberryNAS with:

ifconfig-push 10.8.0.2 255.255.255.0

Listing Active Users

[edit]

To see which users are currently connected:

=== View IP persistence file (shows last assigned IPs) ===
cat /etc/openvpn/server/ipp.txt

== Check active connections via system logs ==
journalctl -u openvpn | grep "Peer Connection Initiated"

== Or check the VPN interface ==
ip addr show tun0

Revoking a User Certificate

[edit]

When a user should no longer have access:

[edit]
   cd /etc/openvpn/server/easy-rsa/

Revoke the certificate:

[edit]
   ./easyrsa revoke clientname
  You'll be prompted to confirm. Type yes.

Update the Certificate Revocation List (CRL):

[edit]
   ./easyrsa gen-crl

Copy the updated CRL to the server directory:

[edit]
   cp pki/crl.pem /etc/openvpn/server/crl.pem

Restart OpenVPN to apply the revocation:

[edit]
   systemctl restart openvpn

Remove client files (optional but recommended):

[edit]
=== Remove .ovpn file ===
   rm /root/clientname.ovpn
   
=== Remove CCD file if it exists ===
   rm /etc/openvpn/ccd/clientname

Note: The revoked certificate will be immediately rejected. The user will not be able to connect even if they still have the .ovpn file.

Security Best Practices

[edit]

Use descriptive client names: Use names that identify the device/user (e.g., laptop-john, phone-mary, nas-synology)

[edit]

Regular certificate rotation: Renew certificates before expiration (typically annually)

[edit]

Revoke unused certificates: Remove access for users who no longer need VPN access

[edit]

Secure .ovpn file distribution: Use secure channels (encrypted email, secure file transfer) when sending .ovpn files to clients

[edit]

Limit static IP assignments: Only assign static IPs when necessary (e.g., for services like the Synology NAS)

[edit]

Monitor active connections: Regularly check who is connected and verify it's expected

[edit]

Keep Easy-RSA secure: The Easy-RSA directory contains sensitive keys - restrict access:

[edit]
   chmod 700 /etc/openvpn/server/easy-rsa/

Backup User Certificates

[edit]

Before making changes, backup user certificates:

=== Backup all certificates and keys ===
tar -czf openvpn-users-backup-$(date +%Y%m%d).tar.gz \
  /etc/openvpn/server/easy-rsa/pki/ \
  /root/*.ovpn \
  /etc/openvpn/ccd/
[edit]
  • [Server Configuration](server-configuration.md) - Server setup
  • [Client Configuration](client-configuration.md) - Client setup
  • [Certificate Management](certificate-management.md) - Certificate details