-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathadd-openvpn-connection-async.py
More file actions
executable file
·135 lines (126 loc) · 5.57 KB
/
add-openvpn-connection-async.py
File metadata and controls
executable file
·135 lines (126 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Example to create a new VPN network connection profile. Currently supported only with tls-auth
#
# $ examples/async/add-openvpn-connection-async.py --help
# usage: add-openvpn-connection.py [-h] [-c CONN_ID] [-d DEV] [--remote REMOTE] [--remote-cert-tls] [-a] [--save]
# [--ca, CA_PATH] [--cert, CERT_PATH] [--key, KEY_path] [--ta, TA_PATH]
#
# Optional arguments have example values:
#
# optional arguments:
# -h, --help show this help message and exit
# -c CONN_ID Connection Id
# -u UUID Connection UUID
# -f OVPN .ovpn connection file
# -a autoconnect
# --save Save
# --ca Path to CA file
# --cert Path to cert file
# --key Path to key file
# --ta Path to tls-auth file
#
# $ add-vpn-connection.py
# New unsaved connection profile created, show it with:
# nmcli connection show "MyConnectionExample"|grep -v -e -- -e default
#
# Connection Profile settings are described at:
# https://networkmanager.dev/docs/api/latest/ref-settings.html
#
# Note: By default, it uses add_connection_unsaved() to add a temporary
# memory-only connection which is not saved to the system-connections folder:
# For reference, see: https://networkmanager.dev/docs/api/latest/spec.html
# -> org.freedesktop.NetworkManager.Settings (Settings Profile Manager)
import asyncio
import functools
import logging
import sdbus
from uuid import uuid4
from argparse import ArgumentParser
from pprint import pformat
from sdbus_async.networkmanager import (
NetworkManagerSettings as SettingsManager,
ConnectionType,
)
from sdbus_async.networkmanager.settings import (
ConnectionProfile,
ConnectionSettings,
Ipv4Settings,
Ipv6Settings,
VpnSettings
)
async def add_vpn_connection_async(conn_id: str,
dev: str,
remote: str,
remote_cert_tls: str,
uuid,
auto: bool,
save: bool,
ca: str,
cert: str,
key: str,
ta: str) -> str:
# Add a temporary (not yet saved) network connection profile
# param Namespace args: dev, remote, remote_cert_tls, ca_path, cert_path, key_path, ta_path
# return: dbus connection path of the created connection profile
info = logging.getLogger().info
# If we add many connections passing the same id, things get messy. Check:
if await SettingsManager().get_connections_by_id(conn_id):
print(f'Connection "{conn_id}" exists, remove it first')
print(f'Run: nmcli connection delete "{conn_id}"')
return ""
profile = ConnectionProfile(
connection=ConnectionSettings(
connection_id=conn_id,
uuid=str(uuid),
connection_type=ConnectionType.VPN.value,
autoconnect=bool(auto),
),
ipv4=Ipv4Settings(method="auto"),
ipv6=Ipv6Settings(method="auto"),
vpn=VpnSettings(data={
'ca': ca,
'cert': cert,
'cert-pass-flags': '0',
'connection-type': 'tls',
'dev': dev,
'key': key,
'remote': remote,
'remote-cert-tls': remote_cert_tls,
'ta': ta,
'ta-dir': '1'
}, service_type='org.freedesktop.NetworkManager.openvpn')
)
s = SettingsManager()
save = bool(save)
addconnection = s.add_connection if save else s.add_connection_unsaved
connection_settings_dbus_path = await addconnection(profile.to_dbus())
created = "created and saved" if save else "created"
info(f"New unsaved connection profile {created}, show it with:")
info(f'nmcli connection show "{conn_id}"|grep -v -e -- -e default')
info("Settings used:")
info(functools.partial(pformat, sort_dicts=False)(profile.to_settings_dict()))
return connection_settings_dbus_path
if __name__ == "__main__":
logging.basicConfig(format="%(message)s", level=logging.INFO)
p = ArgumentParser(description="Optional arguments have example values:")
conn_id = "MyConnectionExample"
p.add_argument("-c", dest="conn_id", default=conn_id, help="Connection Id")
p.add_argument("-u", dest="uuid", default=uuid4(), help="Connection UUID")
p.add_argument("--dev", dest="dev", default="tun", help="VPN Dev")
p.add_argument("--remote", dest="remote", default="example.com:443:tcp", help="VPN Remote")
p.add_argument("--remote-cert-tls", dest="remote_cert_tls", default="server", help="VPN Remote cert tls")
p.add_argument("--ca", dest="ca", required=True, help="VPN CA file path")
p.add_argument("--cert", dest="cert", required=True, help="VPN cert file path")
p.add_argument("--key", dest="key", required=True, help="VPN key file path")
p.add_argument("--ta", dest="ta", required=True, help="VPN TA file path")
p.add_argument("-a", dest="auto", action="store_true", help="autoconnect")
p.add_argument("--save", dest="save", action="store_true", help="Save")
args = p.parse_args()
sdbus.set_default_bus(sdbus.sd_bus_open_system())
if connection_dpath := asyncio.run(add_vpn_connection_async(**vars(args))):
print(f"Path of the new connection: {connection_dpath}")
print(f"UUID of the new connection: {args.uuid}")
else:
print("Error: No new connection created.")