How to Disconnect an OpenVPN Connection via Command Line in Linux Using FreeRADIUS Session Data


2 views

When working with OpenVPN and FreeRADIUS authentication, you might need to programmatically disconnect active VPN sessions. This is particularly useful for administrators who need to manage multiple connections or implement automated session control.

From your FreeRADIUS setup, you typically have access to:

  • Username
  • Client IP address
  • Account-Session-ID
  • NAS-IP-Address
  • Called-Station-ID

First, you'll need to identify the specific OpenVPN process associated with the session:

ps aux | grep openvpn | grep username

Or to find by client IP:

netstat -tnp | grep openvpn | grep client_ip

OpenVPN provides a management interface that can be used to control connections. Here's how to use it:

echo "kill username" | nc -N 127.0.0.1 7505

Note: 7505 is the default management port - adjust if your setup uses a different port.

For a more robust solution, you can create a script that uses FreeRADIUS attributes:

#!/bin/bash
USERNAME=$1
CLIENT_IP=$2
SESSION_ID=$3

# Find the OpenVPN process ID
PID=$(ps aux | grep "openvpn.*$USERNAME" | grep -v grep | awk '{print $2}')

# Gracefully terminate the connection
if [ ! -z "$PID" ]; then
    kill -TERM $PID
    echo "Disconnected session $SESSION_ID for user $USERNAME"
else
    echo "No active session found for user $USERNAME"
fi

You can also use FreeRADIUS's radclient to send a Disconnect-Request packet:

echo "User-Name=$USERNAME, Acct-Session-Id=$SESSION_ID, Event-Timestamp=$(date +%s)" | \
radclient -x NAS_IP_ADDRESS disconnect RADIUS_SECRET
  • Ensure your OpenVPN server is configured with management-hold parameter
  • The management interface should be properly secured
  • FreeRADIUS must be configured to accept Disconnect-Request packets
  • Consider implementing proper logging for audit purposes

Here's a more complete implementation that handles error cases:

#!/bin/bash
# disconnect_vpn.sh - Terminates OpenVPN sessions using FreeRADIUS data

# Configuration
MANAGEMENT_PORT=7505
RADIUS_SECRET="your_shared_secret"
NAS_IP="your.nas.ip"

# Validate input
if [ $# -lt 3 ]; then
    echo "Usage: $0 username client_ip session_id"
    exit 1
fi

USERNAME=$1
CLIENT_IP=$2
SESSION_ID=$3

# Method 1: Try management interface first
echo "Attempting management interface disconnect..."
if echo "kill $USERNAME" | nc -N 127.0.0.1 $MANAGEMENT_PORT 2>/dev/null; then
    echo "Successfully disconnected via management interface"
    exit 0
fi

# Method 2: Try radclient if management interface fails
echo "Management interface failed, trying RADIUS disconnect..."
RADIUS_PACKET="User-Name=$USERNAME
Acct-Session-Id=$SESSION_ID
NAS-IP-Address=$NAS_IP
Called-Station-Id=$CLIENT_IP"

if echo "$RADIUS_PACKET" | radclient -x $NAS_IP disconnect $RADIUS_SECRET; then
    echo "Disconnect request sent via RADIUS"
else
    echo "All disconnect methods failed"
    exit 1
fi

When managing OpenVPN servers integrated with FreeRADIUS authentication, administrators often need to terminate specific sessions programmatically. The standard kill approach for OpenVPN processes doesn't work well in RADIUS-authenticated environments where we need to target specific user sessions.

Here are three reliable approaches to disconnect OpenVPN sessions when you have the following identifiers:

  • Username
  • Client IP
  • AccountSessionID
  • Common name (certificate CN)

First ensure your OpenVPN server has the management interface enabled in the config:

management 127.0.0.1 7505 /etc/openvpn/management.pwd

Then use this bash script to disconnect by username:

#!/bin/bash
OVPN_USER="target_username"
MGMT_SOCKET="127.0.0.1 7505"
PASSWORD=$(cat /etc/openvpn/management.pwd)

{
  sleep 1
  echo "$PASSWORD"
  sleep 1
  echo "kill ${OVPN_USER}"
  sleep 1
} | telnet ${MGMT_SOCKET}

When you need to target specific sessions with RADIUS attributes:

# Disconnect by Account-Session-ID
ACCT_SESSION="a1b2c3d4e5"
pkill -f "openvpn.*acctsessionid=${ACCT_SESSION}"

# Disconnect by client IP
CLIENT_IP="192.168.1.100"
pkill -f "openvpn.*ifconfig-push ${CLIENT_IP}"

For systems with the openvpn-auth-ldap plugin installed:

openvpn-disconnect --client-ip 192.168.1.100 \
  --config /etc/openvpn/server.conf \
  --management /var/run/openvpn.sock

When implementing automated disconnects:

  • Always test in a staging environment first
  • Consider implementing rate limiting
  • Log all administrative disconnects
  • Use sudo or appropriate privileges

Check these logs when disconnects fail:

tail -f /var/log/openvpn/status.log
journalctl -u openvpn@server -f
grep "management" /var/log/openvpn.log