Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

DCO + bind-dev, initial connection binds to interface, but switches to default VRF #683

Open
BCurrell opened this issue Feb 6, 2025 · 6 comments

Comments

@BCurrell
Copy link

BCurrell commented Feb 6, 2025

Describe the bug

When running OpenVPN with DCO enabled, using the bind-dev config directive is not working as expected. The initial connection starts using the interface configured with bind-dev, however after a while, this switches to using the default route interface in the default VRF.

I believe this could be related to when the connection is established, or perhaps if / when the interface offloads to the kernel.

Verified by disabling DCO, when running in TUN mode, the bind-dev config directive works correctly. The connection remains attached to the defined interface.

To Reproduce

DCO config, server:

dev-type tun
dev dco01
port 4001
proto udp

data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305
persist-key
remote-cert-tls client
tls-server

ca /etc/openvpn/keys/rnd/ca.crt
dh /etc/openvpn/dh4096.pem
cert /etc/openvpn/keys/rnd/server.crt
key /etc/openvpn/keys/rnd/server.key

allow-compression no
connect-retry 5 5
fast-io
float
mssfix 1400
max-clients 1
persist-tun
verb 4

DCO config, client:

dev-type tun
dev dco01
port 4001
proto udp

# Testing by binding to a VRF
bind-dev TEST_02
# Also tested with the physical interface within the VRF
# bind-dev eth04
remote <endpoint>

data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305
persist-key
remote-cert-tls server
tls-client

ca /etc/openvpn/keys/rnd/ca.crt
#dh /etc/openvpn/dh4096.pem
cert /etc/openvpn/keys/rnd/client.crt
key /etc/openvpn/keys/rnd/client.key

allow-compression no
connect-retry 5 5
fast-io
float
mssfix 1400
persist-tun
verb 4

For the TUN configs, I just added disable-dco, the rest was left alone.

In my environment, I use networkd to handle the interface configuration. I can provide the networkd config files with the VRF declaration and interface configuration if required.

Expected behavior

The tunnel connects over the bound interface, and continues to use this interface for the whole session.

Version information (please complete the following information):

  • OS: Debian 12.9
  • OpenVPN version:
OpenVPN 2.6.3 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO]
library versions: OpenSSL 3.0.15 3 Sep 2024, LZO 2.10
DCO version: 0.0+git20231103
Originally developed by James Yonan
Copyright (C) 2002-2023 OpenVPN Inc <sales@openvpn.net>
Compile time defines: enable_async_push=no enable_comp_stub=no enable_crypto_ofb_cfb=yes enable_dco=yes enable_dco_arg=yes enable_debug=yes enable_dependency_tracking=no enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown enable_fast_install=needless enable_fragment=yes enable_iproute2=no enable_libtool_lock=yes enable_lz4=yes enable_lzo=yes enable_maintainer_mode=no enable_management=yes enable_option_checking=no enable_pam_dlopen=no enable_pedantic=no enable_pkcs11=yes enable_plugin_auth_pam=yes enable_plugin_down_root=yes enable_plugins=yes enable_port_share=yes enable_selinux=no enable_shared=yes enable_shared_with_static_runtimes=no enable_silent_rules=no enable_small=no enable_static=yes enable_strict=no enable_strict_options=no enable_systemd=yes enable_unit_tests=no enable_werror=no enable_win32_dll=yes enable_wolfssl_options_h=yes enable_x509_alt_username=yes with_aix_soname=aix with_crypto_library=openssl with_gnu_ld=yes with_mem_check=no with_openssl_engine=auto with_sysroot=no
  • Repeat for peer if relevant
    • Same on both sides

Additional context

OpenVPN 2.6.3 was installed from the Debian Bookworm APT repo, however I also built 2.6.13 from release tar.gz from the OpenVPN downloads. The issue is also present there.

@BCurrell
Copy link
Author

BCurrell commented Feb 6, 2025

Image

This is a screenshot of anydump.sh showing the packets starting on TEST_02 (VRF) and eth04 (interface), then switching to eth01 (in default VRF).

Adding the following policy rule is enough to resolve this issue, however that defeats the purpose of binding to an interface:

# 192.168.16.100 is the IP learned from DHCP
# 302 is the table that backs VRF TEST_02

ip rule add from 192.168.16.100 lookup 302

@ordex
Copy link
Member

ordex commented Feb 6, 2025

Hi @BCurrell and thanks for your report.
You're right, DCO currently does not support that specific option and it gets lost when the data channel is offloaded to the kernel.

@BCurrell
Copy link
Author

BCurrell commented Feb 7, 2025

Hi @ordex. Is this something that can be handled, either with a PR to add the feature, or a documentation / code update to state that it's not a valid config?

@ordex
Copy link
Member

ordex commented Feb 7, 2025

@BCurrell IMHO this should first addressed via config handling. I.e. disable DCO when --bind-dev is used.
We already do the same for a bunch of other unsupported options, therefore I think this would be the first step forward.
Are you willing to throw a patch? You can search for "disabling data channel offload" in the openvpn codebase for other similar cases.

@BCurrell
Copy link
Author

BCurrell commented Feb 7, 2025

I'll be honest, the OpenVPN code base is quite intimidating, but I'll take a look at this soon and see if I can figure my way around.

@BCurrell
Copy link
Author

Hi @ordex. I've sent in a PR #690 with my changes. Would love some feedback.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants