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