ovpn_status.py 100% cpu

Started by keeka, August 29, 2025, 02:09:48 PM

Previous topic - Next topic
August 29, 2025, 02:09:48 PM Last Edit: August 29, 2025, 02:11:47 PM by keeka
I am attempting an API script that changes an openvpn client's remote IP and restarts the instance.
This always produces the intended result but on occasion leaves behind an ovpn_status.py process that is consuming 100% cpu, which I then have to kill.
The script retrieves the instance, updates the remote endpoint, restarts the instance, checks the status.
What might I be doing wrong here to cause the runaway process and how better to handle it?
I'm guessing it is related to potential repeated calls to /api/openvpn/service/search_sessions below.

client_name = sys.argv[1]
remote_ip = sys.argv[2]

r = requests.get(
    "{}/api/openvpn/instances/search".format(remote_uri),
    auth=(api_key, api_secret),
    verify=False
)
if r.status_code != 200:
    print("error : %s" % r.text)
    sys.exit(1)

instances = json.loads(r.text)

for row in instances['rows']:
    if row['description'] == client_name and row['role'] == 'client':
        uuid = row['uuid']

        instance = {
            "instance": {
                "remote": remote_ip,
            }
        }

        print("Changing remote from {} to {}".format(row['remote'], remote_ip))

        r = requests.post(
            "{}/api/openvpn/instances/set/{}".format(remote_uri, uuid),
            auth=(api_key, api_secret),
            verify=False,
            json=instance
        )
        if r.status_code != 200:
            print("error setting new remote: %s" % r.text)
            sys.exit(1)

        if row['enabled'] == '0':
            print("instance {} disabled. Skipping restart".format(client_name))
            sys.exit(0)

        print("restarting {}...".format(client_name))
        r = requests.post(
            "{}/api/openvpn/service/restart_service/{}".format(remote_uri, uuid),
            auth=(api_key, api_secret),
            verify=False
        )
        if r.status_code != 200:
            print("error restarting: %s" % r.text)
            sys.exit(1)

        sleep_time = 5
        num_checks = 3
        while num_checks > 0:
            time.sleep(sleep_time)
            num_checks -= 1
            r = requests.post(
                "{}/api/openvpn/service/search_sessions".format(remote_uri),
                auth=(api_key, api_secret),
                verify=False
            )
            if r.status_code != 200:
                print("error checking status after restart: %s" % r.text)
                sys.exit(1)
            statuses = json.loads(r.text)
            for s in statuses['rows']:
                if s['id'] == uuid and s['status'] == 'connected':
                    client_status_str = "{} {} {} {} {} {}".format(
                        s['description'],
                        s['status'],
                        s['real_address'],
                        s['virtual_address'],
                        s['bytes_sent'],
                        s['bytes_received']
                    )
                    print("Success {}".format(client_status_str))
                    sys.exit(0)
        print("{} failed to (re)start".format(client_name))
        sys.exit(1)

print("No matching vpn client instance found")
sys.exit(1)


Hello,

I have the same issue here:

root@OPNsense:~ # ps auxwww|grep python
root    9967 100.0  0.6 29144 12412  -  R    Tue05   2106:46.85 /usr/local/bin/python3 /usr/local/opnsense/scripts/openvpn/ovpn_status.py --option client,server (python3.11)
root   48097  18.1  1.6 53672 32428  -  Ss   Tue03     87:00.26 /usr/local/bin/python3 /usr/local/opnsense/scripts/netflow/flowd_aggregate.py (python3.11)
root     437   0.0  0.0 28108     8  -  IWs  -          0:00.00 /usr/local/bin/python3 /usr/local/opnsense/service/configd.py (python3.11)
root     439   0.0  1.1 81708 23184  -  I    Tue03      0:29.31 /usr/local/bin/python3 /usr/local/opnsense/service/configd.py console (python3.11)
root   31822   0.0  0.6 27368 12372  -  S    Tue03      0:18.60 /usr/local/bin/python3 /usr/local/sbin/configctl -e -t 0.5 system event config_changed (python3.11)
root   31902   0.0  0.6 28392 12760  -  S    Tue03      0:18.40 /usr/local/bin/python3 /usr/local/opnsense/scripts/syslog/lockout_handler (python3.11)

Worst decision I took since using OPNSense was to migrate to OpenVPN Instances.

CPU always at 100%, my connection lost traffic each exaclty hour (for example, 17:00, 18:00...).

ovpn_status.py should, when called, return the specified instances json and exit. For me, it generally completes successfully other than the odd time when using the api to restart and check an instance. I never see the issue otherwise. Does your setup involve restarting openvpn instance(s) on the hour?