travisghansen / hass-opnsense

OPNsense integration with Home Assistant
Apache License 2.0
230 stars 29 forks source link

[Bug]: OpenVPN Sensor information is inaccurate #290

Closed Snuffy2 closed 1 month ago

Snuffy2 commented 1 month ago

What happened?

From reviewing the logic for the OPNsense OpenVPN Dashboard Widget and looking at a bunch more REST API results, the current OpenVPN Sensors are not very accurate.

I believe I can accurately show the number of clients connected to a server and the throughput of a server. I can additionally show details about the connected clients as they relate to the server. However, I don't see any way to link the list of connected client details to the actual clients created. Thus, I'm not sure if I will be able to have accurate client sensors.

I'll continue to explore. @jesmak or anyone else, let me know if you're interested in helping to untangle this.

https://docs.opnsense.org/development/api/core/openvpn.html https://github.com/opnsense/core/blob/8e41be2ebe8b53d59fded39d289c5d73822c8083/src/opnsense/www/js/widgets/OpenVPNClients.js https://github.com/opnsense/core/blob/8e41be2ebe8b53d59fded39d289c5d73822c8083/src/opnsense/www/js/widgets/OpenVPNServers.js

The OpenVPN Server and Client switches are not affected by this.

hass-opnsense Version

v0.3.7

OPNsense Firmware

24.7

Home Assistant Version

2024.10

Relevant logs

No response

Additional Details

No response

Snuffy2 commented 1 month ago

This is a translation of the OpenVPNClients.js function into Python. It shows how it is taking the output of /api/openvpn/service/search_sessions and "interpreting" it.

    async def openvpn_widget(self) -> None:
        sessions = await self._post(
            "/api/openvpn/service/search_sessions", payload={"type": ["server"]}
        )
        _LOGGER.debug(f"[openvpn_widget] sessions: {sessions}")

        if not sessions or "rows" not in sessions or len(sessions["rows"]) == 0:
            _LOGGER.debug("[openvpn_widget] No sessions")

        servers = {}
        for session in sessions.get("rows", []):
            server_id = str(session["id"]).split("_")[0]

            if server_id not in servers:
                servers[server_id] = {
                    "description": session.get("description", ""),
                    "clients": [],
                }

            if not session.get("is_client", False):
                servers[server_id] = session
                servers[server_id]["clients"] = None
            else:
                servers[server_id]["clients"].append(session)
        _LOGGER.debug(f"[openvpn_widget] servers: {servers}")

This is the output of the function with one server:

No clients connected:

{
    'a90bf93b-0c67-4aea-9beb-5a96c6a956ee': {
        'status': 'ok',
        'type': 'server',
        'id': 'a90bf93b-0c67-4aea-9beb-5a96c6a956ee',
        'description': 'Snuffy2 OpenVPN',
        'clients': None
    }
}

One client connected:

{
    'a90bf93b-0c67-4aea-9beb-5a96c6a956ee': {
        'description': 'Snuffy2 OpenVPN',
        'clients': [
            {
                'status': 'ok',
                'type': 'server',
                'id': 'a90bf93b-0c67-4aea-9beb-5a96c6a956ee_111.111.111.111:63795',
                'description': 'Snuffy2 OpenVPN',
                'common_name': 'snuffy2-ca',
                'real_address': '111.111.111.111:63795',
                'virtual_address': '10.100.4.2',
                'virtual_ipv6_address': '',
                'bytes_received': '9721',
                'bytes_sent': '13256',
                'connected_since': '2024-10-22 22:06:46',
                'connected_since__time_t_': '1729649206',
                'username': 'UNDEF',
                'client_id': '335',
                'peer_id': '0',
                'data_channel_cipher': 'AES-256-GCM',
                'is_client': True
            }
        ]
    }
}
jesmak commented 1 month ago

@Snuffy2 Just let me know if there's something specific you need help with and I'll be happy to help

Snuffy2 commented 1 month ago

@jesmak and anyone else, please give v0.3.8-beta.2 a try and see how the OpenVPN Server Sensors are functioning. The OpenVPN Client sensors wont work.

Snuffy2 commented 1 month ago

@jesmak and anyone else, would you be willing to email me an only minimally redacted output from some of the OPNsense OpenVPN queries? I won't post or send them anywhere else and just want to use them to see if there's anyway to link the servers to the clients in the API data.

Queries: /api/openvpn/export/providers /api/openvpn/service/searchSessions /api/openvpn/service/searchRoutes (I know these may be blank if you are using the legacy setup, but please still confirm this) /api/openvpn/instances/search /api/openvpn/instances/get

Please email them to github@mail.snuffy2.com

jesmak commented 1 month ago

I sent you an email with the outputs you requested. I'll test the beta release next.

jesmak commented 1 month ago

Server sensors seem to be working fine with the beta release. Download/upload speeds are shown for both of my OpenVPN configurations, total byte counts also increase when downloading.

Snuffy2 commented 1 month ago

@jesmak Thanks so much for the details!!! It helped me validate the server API data.

One last thing. On the OPNsense Dashboard, if you add the OpenVPN Server and OpenVPN Client Widgets what do they show? Feel free to email me a screenshot.

2024-10-25_07-56-14 924

jesmak commented 1 month ago

I sent the relevant info via email.