nmcli: Add wireguard connection type support (#3985)

* nmcli: add wireguard connection type

* nmcli: fix wireguard unit tests

* nmcli: set ipv4.method to disabled if ip4 not set

Method 'auto' is not supported for WireGuard

* nmcli: add wireguard documentation

* nmcli: clean up wireguard documentation

* nmcli: add wireguard changelog fragment

* nmcli: fix wireguard documentation

* Apply suggestions from code review

Co-authored-by: Andrew Pantuso <ajpantuso@gmail.com>

Co-authored-by: Andrew Pantuso <ajpantuso@gmail.com>
This commit is contained in:
Johan Wennerberg 2022-01-08 14:13:50 +01:00 committed by GitHub
parent 26a91e811f
commit 4ea58fba75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 218 additions and 3 deletions

View file

@ -55,8 +55,10 @@ options:
- Type C(generic) is added in Ansible 2.5.
- Type C(infiniband) is added in community.general 2.0.0.
- Type C(gsm) is added in community.general 3.7.0.
- Type C(wireguard) is added in community.general 4.3.0
type: str
choices: [ bond, bond-slave, bridge, bridge-slave, dummy, ethernet, generic, gre, infiniband, ipip, sit, team, team-slave, vlan, vxlan, wifi, gsm ]
choices: [ bond, bond-slave, bridge, bridge-slave, dummy, ethernet, generic, gre, infiniband, ipip, sit, team, team-slave, vlan, vxlan, wifi, gsm,
wireguard ]
mode:
description:
- This is the type of device or network connection that you wish to create for a bond or bridge.
@ -754,6 +756,62 @@ options:
- The username used to authenticate with the network, if required.
- Many providers do not require a username, or accept any username.
- But if a username is required, it is specified here.
wireguard:
description:
- The configuration of the Wireguard connection.
- Note the list of suboption attributes may vary depending on which version of NetworkManager/nmcli is installed on the host.
- 'An up-to-date list of supported attributes can be found here:
U(https://networkmanager.dev/docs/api/latest/settings-wireguard.html).'
- 'For instance to configure a listen port:
C({listen-port: 12345}).'
type: dict
version_added: 4.3.0
suboptions:
fwmark:
description:
- The 32-bit fwmark for outgoing packets.
- The use of fwmark is optional and is by default off. Setting it to 0 disables it.
- Note that I(wireguard.ip4-auto-default-route) or I(wireguard.ip6-auto-default-route) enabled, implies to automatically choose a fwmark.
type: int
ip4-auto-default-route:
description:
- Whether to enable special handling of the IPv4 default route.
- If enabled, the IPv4 default route from I(wireguard.peer-routes) will be placed to a dedicated routing-table and two policy
routing rules will be added.
- The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, an unused fwmark/table is chosen
automatically. This corresponds to what wg-quick does with Table=auto and what WireGuard calls "Improved Rule-based Routing"
type: bool
ip6-auto-default-route:
description:
- Like I(wireguard.ip4-auto-default-route), but for the IPv6 default route.
type: bool
listen-port:
description: The WireGuard connection listen-port. If not specified, the port will be chosen randomly when the
interface comes up.
type: int
mtu:
description:
- If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments.
- If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes
at the time of activation.
type: int
peer-routes:
description:
- Whether to automatically add routes for the AllowedIPs ranges of the peers.
- If C(true) (the default), NetworkManager will automatically add routes in the routing tables according to C(ipv4.route-table) and
C(ipv6.route-table). Usually you want this automatism enabled.
- If C(false), no such routes are added automatically. In this case, the user may want to configure static routes in C(ipv4.routes)
and C(ipv6.routes), respectively.
- Note that if the peer's AllowedIPs is C(0.0.0.0/0) or C(::/0) and the profile's C(ipv4.never-default) or C(ipv6.never-default)
setting is enabled, the peer route for this peer won't be added automatically.
type: bool
private-key:
description: The 256 bit private-key in base64 encoding.
type: str
private-key-flags:
description: C(NMSettingSecretFlags) indicating how to handle the I(wireguard.private-key) property.
type: int
choices: [ 0, 1, 2 ]
'''
EXAMPLES = r'''
@ -1126,6 +1184,17 @@ EXAMPLES = r'''
autoconnect: true
state: present
- name: Create a wireguard connection
community.general.nmcli:
type: wireguard
conn_name: my-wg-provider
ifname: mywg0
wireguard:
listen-port: 51820
private-key: my-private-key
autoconnect: true
state: present
'''
RETURN = r"""#
@ -1236,10 +1305,11 @@ class Nmcli(object):
self.wifi = module.params['wifi']
self.wifi_sec = module.params['wifi_sec']
self.gsm = module.params['gsm']
self.wireguard = module.params['wireguard']
if self.method4:
self.ipv4_method = self.method4
elif self.type == 'dummy' and not self.ip4:
elif self.type in ('dummy', 'wireguard') and not self.ip4:
self.ipv4_method = 'disabled'
elif self.ip4:
self.ipv4_method = 'manual'
@ -1248,7 +1318,7 @@ class Nmcli(object):
if self.method6:
self.ipv6_method = self.method6
elif self.type == 'dummy' and not self.ip6:
elif self.type in ('dummy', 'wireguard') and not self.ip6:
self.ipv6_method = 'disabled'
elif self.ip6:
self.ipv6_method = 'manual'
@ -1404,6 +1474,12 @@ class Nmcli(object):
options.update({
'gsm.%s' % name: value,
})
elif self.type == 'wireguard':
if self.wireguard:
for name, value in self.wireguard.items():
options.update({
'wireguard.%s' % name: value,
})
# Convert settings values based on the situation.
for setting, value in options.items():
setting_type = self.settings_type(setting)
@ -1445,6 +1521,7 @@ class Nmcli(object):
'vlan',
'wifi',
'gsm',
'wireguard',
)
@property
@ -1834,6 +1911,7 @@ def main():
'vxlan',
'wifi',
'gsm',
'wireguard',
]),
ip4=dict(type='list', elements='str'),
gw4=dict(type='str'),
@ -1907,6 +1985,7 @@ def main():
wifi=dict(type='dict'),
wifi_sec=dict(type='dict', no_log=True),
gsm=dict(type='dict'),
wireguard=dict(type='dict'),
),
mutually_exclusive=[['never_default4', 'gw4']],
required_if=[("type", "wifi", [("ssid")])],