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?

Hello @keeka,

No, I only restart once a day—when I update the NordVPN servers and reconnect. However, every hour, my four connections drop without actually disconnecting or reconnecting. It's as if they're renegotiating, even though the renegotiation time is set to 0.