tonyseek / openvpn-status

Parse OpenVPN status logs in Python
https://openvpn-status.readthedocs.io
MIT License
83 stars 31 forks source link

Client_list and routing_table have different addresses #8

Closed rohithasrk closed 6 years ago

rohithasrk commented 6 years ago

Is there any particular reason virtual address is being used in routing_table whereas real address in client_list @tonyseek? https://github.com/tonyseek/openvpn-status/blob/0bfd6753cdb3d2574d63db8c8db03a841c143c96/openvpn_status/parser.py#L91

rohithasrk commented 6 years ago

At OpenWISP, we are making an OpenVPN status parser to return a networkx graph. The code can be seen here https://github.com/ninuxorg/netdiff/blob/master/netdiff/parsers/openvpn.py

tonyseek commented 6 years ago

Hi @rohithasrk,

This is a breaking change of 0.2 release. The origin is that I chose common_name as the key of client_list and routing_table but the common_name is not unique in two lists both (GH-2). By testing with a OpenVPN server, I found that real_address is unique in client_list and virutal_address is unique in routing_table.

The real_address duplicates in routing_table if the client-config-dir and iroute are enabled. The openvpn-status.log looks like:

OpenVPN CLIENT LIST
Updated,Thu Jun 18 08:12:15 2015
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
foo@example.com,10.10.10.10:42102,334948,1973012,Thu Jun 18 04:23:03 2015
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
192.168.255.134,foo@example.com,10.10.10.10:42102,Thu Jun 18 04:23:03 2015
10.200.0.0/16,foo@example.com,10.10.10.10:42102,Thu Jun 18 04:23:03 2015
GLOBAL STATS
Max bcast/mcast queue length,0
END

For the requirement of OpenWISP, I suggest to iterate the routing_table:

        for client in data.client_list.values():
            client_properties = {
                'real_address': str(client.real_address.host),
                'port': client.real_address.port,
                'connected_since': client.connected_since.strftime('%Y-%m-%dT%H:%M:%SZ'),
                'bytes_received': client.bytes_received,
                'bytes_sent': client.bytes_sent
            }
            local_addresses = [
                str(route.virtual_address)
                for route in data.routing_table.values()
                if route.real_address == client.real_address
                if not isinstance(route.virtual_address, (
                    ipaddress.IPv4Network, ipaddress.IPv6Network))  # If you don't need the subnet of CCD
            ]
            if local_addresses:
                client_properties['local_addresses'] = local_addresses
            graph.add_node(common_name, **client_properties)
rohithasrk commented 6 years ago

I see @tonyseek. Thank you :smile:

tonyseek commented 6 years ago

You are welcome 😄