lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <99028055-f440-45e8-8fb1-ec4e19e0cafa@openvpn.net>
Date: Tue, 17 Sep 2024 23:28:41 +0200
From: Antonio Quartulli <antonio@...nvpn.net>
To: Donald Hunter <donald.hunter@...il.com>
Cc: netdev@...r.kernel.org, kuba@...nel.org, pabeni@...hat.com,
 ryazanov.s.a@...il.com, edumazet@...gle.com, andrew@...n.ch,
 sd@...asysnail.net
Subject: Re: [PATCH net-next v7 04/25] ovpn: add basic netlink support

Hi Donald,

On 17/09/2024 15:23, Donald Hunter wrote:
> Antonio Quartulli <antonio@...nvpn.net> writes:
> 
>> This commit introduces basic netlink support with family
>> registration/unregistration functionalities and stub pre/post-doit.
>>
>> More importantly it introduces the YAML uAPI description along
> 
> Hi Antonio,
> 
> net-next is currently closed so my guess is that you'll have to resend
> this when net-next reopens at the end of the month:
> 
> https://netdev.bots.linux.dev/net-next.html

I quickly discussed this point with Sabrina and the conclusion was that 
posting shouldn't hurt as this patchset is not truly "a new submission".
In any case, I'll see if more comments come through or not first.

> 
> I have read through the YAML spec and I have few comments (and nits)
> below.

Thanks a lot. My replies are inline.

> 
> Thanks,
> Donald.
> 
>> diff --git a/Documentation/netlink/specs/ovpn.yaml b/Documentation/netlink/specs/ovpn.yaml
>> new file mode 100644
>> index 000000000000..456ac3747d27
>> --- /dev/null
>> +++ b/Documentation/netlink/specs/ovpn.yaml
>> @@ -0,0 +1,328 @@
>> +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
>> +#
>> +# Author: Antonio Quartulli <antonio@...nvpn.net>
>> +#
>> +# Copyright (c) 2024, OpenVPN Inc.
>> +#
>> +
>> +name: ovpn
>> +
>> +protocol: genetlink
>> +
>> +doc: Netlink protocol to control OpenVPN network devices
>> +
>> +definitions:
>> +  -
>> +    type: const
>> +    name: nonce-tail-size
>> +    value: 8
>> +  -
>> +    type: enum
>> +    name: cipher-alg
>> +    value-start: 0
>> +    entries: [ none, aes-gcm, chacha20_poly1305 ]
> 
> Nit: Is there any reason for the underscore in chacha20_poly1305 and the
> mixed use of dash / underscore in various identifiers throughout the
> spec? The YNL convention is to use dashes throughout.

No real reason, I must have not realized that I Was mixing the two.
I will convert them all to dashes.


> 
>> +  -
>> +    type: enum
>> +    name: del-peer_reason
>> +    value-start: 0
>> +    entries: [ teardown, userspace, expired, transport-error, transport_disconnect ]
>> +  -
>> +    type: enum
>> +    name: key-slot
>> +    value-start: 0
>> +    entries: [ primary, secondary ]
>> +  -
>> +    type: enum
>> +    name: mode
>> +    value-start: 0
>> +    entries: [ p2p, mp ]
>> +
>> +attribute-sets:
>> +  -
>> +    name: peer
>> +    attributes:
>> +      -
>> +        name: id
>> +        type: u32
>> +        doc: |
>> +          The unique Id of the peer. To be used to identify peers during
>> +          operations
>> +        checks:
>> +          max: 0xFFFFFF
>> +      -
>> +        name: sockaddr-remote
>> +        type: binary
>> +        doc: |
>> +          The sockaddr_in/in6 object identifying the remote address/port of the
>> +          peer
> 
> The use of structs as attribute values is strongly discouraged. There
> should be separate attributes for port and ipv[46]-address.
> 
> https://docs.kernel.org/userspace-api/netlink/intro.html#fixed-metadata-and-structures

Thanks a lot for the pointer! I didn't know that.
This means I have to change the netlink attributes as per your 
suggestion (address, port, scope_id) and recreate the sockaddr on the 
kernel side.

> 
>> +      -
>> +        name: socket
>> +        type: u32
>> +        doc: The socket to be used to communicate with the peer
>> +      -
>> +        name: vpn-ipv4
>> +        type: u32
>> +        doc: The IPv4 assigned to the peer by the server
> 
> nit: IPv4 address

ACK

> 
>> +        display-hint: ipv4
>> +      -
>> +        name: vpn-ipv6
>> +        type: binary
>> +        doc: The IPv6 assigned to the peer by the server
> 
> nit: IPv6 address

ACK

> 
>> +        display-hint: ipv6
>> +        checks:
>> +          exact-len: 16
>> +      -
>> +        name: local-ip
>> +        type: binary
>> +        doc: The local IP to be used to send packets to the peer (UDP only)
>> +        checks:
>> +          max-len: 16
> 
> It might be better to have separate attrs fopr local-ipv4 and
> local-ipv6, to be consistent with vpn-ipv4 / vpn-ipv6

while it is possible for a peer to be dual stack and have both an IPv4 
and IPv6 address assigned to the VPN tunnel, the local transport 
endpoint can only be one (either v4 or v6).
This is why we have only one local_ip.
Does it make sense?

> 
>> +      -
>> +        name: local-port
>> +        type: u32
>> +        doc: The local port to be used to send packets to the peer (UDP only)
>> +        checks:
>> +          min: 1
>> +          max: u16-max
>> +      -
>> +        name: keepalive-interval
>> +        type: u32
>> +        doc: |
>> +          The number of seconds after which a keep alive message is sent to the
>> +          peer
>> +      -
>> +        name: keepalive-timeout
>> +        type: u32
>> +        doc: |
>> +          The number of seconds from the last activity after which the peer is
>> +          assumed dead
>> +      -
>> +        name: del-reason
>> +        type: u32
>> +        doc: The reason why a peer was deleted
>> +        enum: del-peer_reason
>> +      -
>> +        name: keyconf
>> +        type: nest
>> +        doc: Peer specific cipher configuration
>> +        nested-attributes: keyconf
> 
> Perhaps keyconf should just be used as a top-level attribute-set. The
> only attr you'd need to duplicate would be peer-id? There are separate
> ops for setting peers and for key configuration, right?

This is indeed a good point.
Yes, SET_PEER and SET_KEY are separate ops.

I could go with SET_PEER only, and let the user specify a keyconf within 
a peer (like now).

Or I could keep to SET_KEY, but then do as you suggest and move KEYCONF 
to the root level.

Is there any preferred approach?

> 
>> +      -
>> +        name: vpn-rx_bytes
>> +        type: uint
>> +        doc: Number of bytes received over the tunnel
>> +      -
>> +        name: vpn-tx_bytes
>> +        type: uint
>> +        doc: Number of bytes transmitted over the tunnel
>> +      -
>> +        name: vpn-rx_packets
>> +        type: uint
>> +        doc: Number of packets received over the tunnel
>> +      -
>> +        name: vpn-tx_packets
>> +        type: uint
>> +        doc: Number of packets transmitted over the tunnel
>> +      -
>> +        name: link-rx_bytes
>> +        type: uint
>> +        doc: Number of bytes received at the transport level
>> +      -
>> +        name: link-tx_bytes
>> +        type: uint
>> +        doc: Number of bytes transmitted at the transport level
>> +      -
>> +        name: link-rx_packets
>> +        type: u32
>> +        doc: Number of packets received at the transport level
>> +      -
>> +        name: link-tx_packets
>> +        type: u32
>> +        doc: Number of packets transmitted at the transport level
>> +  -
>> +    name: keyconf
>> +    attributes:
>> +      -
>> +        name: slot
>> +        type: u32
>> +        doc: The slot where the key should be stored
>> +        enum: key-slot
>> +      -
>> +        name: key-id
>> +        doc: |
>> +          The unique ID for the key. Used to fetch the correct key upon
>> +          decryption
>> +        type: u32
>> +        checks:
>> +          max: 7
>> +      -
>> +        name: cipher-alg
>> +        type: u32
>> +        doc: The cipher to be used when communicating with the peer
>> +        enum: cipher-alg
>> +      -
>> +        name: encrypt-dir
>> +        type: nest
>> +        doc: Key material for encrypt direction
>> +        nested-attributes: keydir
>> +      -
>> +        name: decrypt-dir
>> +        type: nest
>> +        doc: Key material for decrypt direction
>> +        nested-attributes: keydir
>> +  -
>> +    name: keydir
>> +    attributes:
>> +      -
>> +        name: cipher-key
>> +        type: binary
>> +        doc: The actual key to be used by the cipher
>> +        checks:
>> +         max-len: 256
>> +      -
>> +        name: nonce-tail
>> +        type: binary
>> +        doc: |
>> +          Random nonce to be concatenated to the packet ID, in order to
>> +          obtain the actua cipher IV
>> +        checks:
>> +         exact-len: nonce-tail-size
>> +  -
>> +    name: ovpn
>> +    attributes:
>> +      -
>> +        name: ifindex
>> +        type: u32
>> +        doc: Index of the ovpn interface to operate on
>> +      -
>> +        name: ifname
>> +        type: string
>> +        doc: Name of the ovpn interface that is being created
>> +      -
>> +        name: mode
>> +        type: u32
>> +        enum: mode
>> +        doc: |
>> +          Oper mode instructing an interface to act as Point2Point or
>> +          MultiPoint
>> +      -
>> +        name: peer
>> +        type: nest
>> +        doc: |
>> +          The peer object containing the attributed of interest for the specific
>> +          operation
>> +        nested-attributes: peer
>> +
>> +operations:
>> +  list:
>> +    -
>> +      name: new-iface
> 
> This might be better called 'dev' or 'link' to be consistent with the
> existing netlink UAPIs.

hm ok, then I think I will s/IFACE/DEV/

> 
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Create a new interface
>> +      do:
>> +        request:
>> +          attributes:
>> +            - ifname
>> +            - mode
>> +        reply:
>> +          attributes:
>> +            - ifname
>> +            - ifindex
>> +    -
>> +      name: del-iface
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Delete existing interface
>> +      do:
>> +        pre: ovpn-nl-pre-doit
>> +        post: ovpn-nl-post-doit
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +    -
>> +      name: set-peer
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Add or modify a remote peer
>> +      do:
>> +        pre: ovpn-nl-pre-doit
>> +        post: ovpn-nl-post-doit
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +            - peer
>> +    -
>> +      name: get-peer
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Retrieve data about existing remote peers (or a specific one)
>> +      do:
>> +        pre: ovpn-nl-pre-doit
>> +        post: ovpn-nl-post-doit
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +            - peer
>> +        reply:
>> +          attributes:
>> +            - peer
>> +      dump:
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +        reply:
>> +          attributes:
>> +            - peer
>> +    -
>> +      name: del-peer
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Delete existing remote peer
>> +      do:
>> +        pre: ovpn-nl-pre-doit
>> +        post: ovpn-nl-post-doit
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +            - peer
> 
> I think you need to add an op for 'del-peer-notify' to specify the
> notification, not reuse the 'del-peer' command.

my idea was to use CMD_DEL_PEER and then send back a very very short 
PEER object.
I took inspiration from nl80211 that sends CMD_NEW_STATION and 
CMD_DEL_STATION when a wifi host connects or disconnect. In that case 
the full STATION object is also delivered (maybe I should do the same?)

Or is there some other technical reason for not reusing CMD_DEL_PEER?

> 
>> +    -
>> +      name: set-key
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Add or modify a cipher key for a specific peer
>> +      do:
>> +        pre: ovpn-nl-pre-doit
>> +        post: ovpn-nl-post-doit
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +            - peer
>> +    -
>> +      name: swap-keys
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Swap primary and secondary session keys for a specific peer
>> +      do:
>> +        pre: ovpn-nl-pre-doit
>> +        post: ovpn-nl-post-doit
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +            - peer
> 
> Same for swap-keys notifications.

Yeah, here I can understand. My rationale was: tell userspace that now 
we truly need a SWAP_KEYS. Do you think this can create problems/confusion?

> 
>> +    -
>> +      name: del-key
>> +      attribute-set: ovpn
>> +      flags: [ admin-perm ]
>> +      doc: Delete cipher key for a specific peer
>> +      do:
>> +        pre: ovpn-nl-pre-doit
>> +        post: ovpn-nl-post-doit
>> +        request:
>> +          attributes:
>> +            - ifindex
>> +            - peer
>> +
>> +mcast-groups:
>> +  list:
>> +    -
>> +      name: peers

Thanks a lot for your comments, Donald!

Regards,


-- 
Antonio Quartulli
OpenVPN Inc.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ