OpenVPN / openvpn

OpenVPN is an open source VPN daemon
http://openvpn.net
Other
10.25k stars 2.92k forks source link

Allow modifying OpenVPN internal routing table #424

Open nielsek opened 8 months ago

nielsek commented 8 months ago

Describe the feature

Description copied from the old issue tracker: https://community.openvpn.net/openvpn/ticket/1046

On OpenVPN server side, when you want to route a network to a specific client, you add route directive to server config file (adds route to system routing table) and iroute directive to client config file in ccd directory (adds route to OpenVPN internal routing table). However, if the client is already connected, it needs to disconnect and reconnect in order for route to become active. I'd like to have the ability to activate the route without dropping client connection. Adding a route to system routing table is easy enough, but there is no way (that I can see) to modify OpenVPN internal routing table. Please allow modifying the internal routing table via management interface or some other means.

Implementation behavior

In the old issue there is a reference to an implementation of this feature that @selvanair has made, which adds a new --add-iroute management command: https://github.com/selvanair/openvpn/commits/manage-add-iroute

The implementation was never proposed as a PR due to the lack of a way of deleting routes in the same fashion, however as later discussed in the old issue, the implementation does support overwriting routes, and deletion of routes will still happen on client reconnect if not persisted to config. That is perfectly fine, at least for our usecase, where dynamic routes are appended to config (never deleted).

Implementation description from https://github.com/selvanair/openvpn/commit/73825fee644167d0c9efc1b1e085337f1d45fffa :

Implement a new management command

   --add-iroute network/bits destination

This adds an internal route to target specified as network/bits
via client specified by "destination". The latter could be
the VPN ifconfig_local IP of the client (IPv4 or IPv6), the client-id
(CID) of the client or a string "CN:common-name" obtained by prepending
"CN:" to the common-name of the client.

Note that the destination address is not the real-ip of the client
unlike in kill-by-addr command.

The target network must be an IPv4 or IPv6 network address with
bits specifying the prefix length. If /bits is omitted, it defaults
to 32 for IPv4 or 64 for IPv6 matchig with the --iroute and
--iroute-ipv6 options in the client-specific config files.

Examples:
   add-iroute 192.168.5.0/24 21          # client by CID
   add-iroute 2001::0b:/64 2001::0a:1005 # client by IPv6
   add-iroute 192.168.10.11 10.11.0.6    # host route, client by IPv4

Notes:
(i) Client-id as destination is available only if the daemon is built with
MANAGEMENT_DEF_AUTH support (this is the default unless --disable-def-auth
is used while configuring)

(ii) As the common-name need not be unique, the first client that matches
the specified name is used

(iii) These routes do not persist across reconnections. For persistent
iroutes also add a matching iroute directive to the ccd file for the client.

(iv) The route for a client is added only if the client has completed
authentication, ccd-file parsing and client-connect-script, if any.

Signed-off-by: Selva Nair <selva.nair@gmail.com>

Additional context

This feature would be very helpful for us, since we are currently disturbing all VPN traffic when a new route is added, which happens dynamically.

cron2 commented 8 months ago

Routes need not be created by stopping/starting the openvpn process - just calling ip route add ... dev tunX to add a route to an existing tunX will work fine (and iroute will work fine even if OpenVPN did not configure the route in question).

This said, if you use DCO (2.6.0 and up, on Linux and FreeBSD), iroutes are always system routes, so the "dynamic iroute" part is already happening (because DCO is not using the internal OpenVPN server routing table any longer).

selvanair commented 8 months ago

The feature was about dynamically changing iroutes after updating the OS's routing table. The latter can be altered without restarting the server but changing the iroute table currently needs a server restart.

That said, the patch was made a long time ago and is probably untested. I did not follow up as personally I haven't felt a real need for this. Not sure whether it's worthwhile to spend time to resurrect it.

ordex commented 2 months ago

@cron2 should we consider this ticket as won't fix, since the requested behavior can be implemented by using DCO?

cron2 commented 2 months ago

It can't. See Selva's last post.