diff --git a/README.md b/README.md index c270bd3..2861931 100644 --- a/README.md +++ b/README.md @@ -362,6 +362,26 @@ So both provide an additional layer of security and mitigate DoS attacks. They a The script supports both and uses `tls-crypt` by default. +### Data Channel Offload (DCO) + +[Data Channel Offload](https://openvpn.net/as-docs/openvpn-data-channel-offload.html) (DCO) is a kernel acceleration feature that significantly improves OpenVPN performance by keeping data channel encryption/decryption in kernel space, eliminating costly context switches between user and kernel space for each packet. + +DCO was merged into the Linux kernel 6.16 (April 2025). + +**Requirements:** + +- OpenVPN 2.6.0 or later +- Linux kernel 6.16+ (built-in) or `ovpn-dco` kernel module +- UDP protocol (TCP is not supported) +- AEAD cipher (`AES-128-GCM`, `AES-256-GCM`, or `CHACHA20-POLY1305`) +- Compression disabled + +The script's default settings (AES-128-GCM, UDP, no compression) are DCO-compatible. When DCO is available and the configuration is compatible, OpenVPN will automatically use it for improved performance. + +**Note:** DCO must be supported on both the server and the client for full acceleration. Client support is available in OpenVPN 2.6+ (Linux, Windows, FreeBSD) and OpenVPN Connect 3.4+ (Windows). macOS does not currently support DCO, but clients can still connect to DCO-enabled servers with partial performance benefits on the server-side. + +The script will display the DCO availability status during installation. + ## Say thanks You can [say thanks](https://saythanks.io/to/angristan) if you want! diff --git a/openvpn-install.sh b/openvpn-install.sh index 5a6010f..28e8040 100755 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -257,6 +257,42 @@ function openvpnVersionAtLeast() { return 1 } +# Check if kernel version is at least the specified version +# Usage: kernelVersionAtLeast "6.16" +# Returns 0 if version is >= specified, 1 otherwise +function kernelVersionAtLeast() { + local required_version="$1" + local kernel_version + + kernel_version=$(uname -r | cut -d'-' -f1) + if [[ -z "$kernel_version" ]]; then + return 1 + fi + + if [[ "$(printf '%s\n' "$required_version" "$kernel_version" | sort -V | head -n1)" == "$required_version" ]]; then + return 0 + fi + return 1 +} + +# Check if Data Channel Offload (DCO) is available +# DCO requires: OpenVPN 2.6+, kernel support (Linux 6.16+ or ovpn-dco module) +# Returns 0 if DCO is available, 1 otherwise +function isDCOAvailable() { + # DCO requires OpenVPN 2.6+ + if ! openvpnVersionAtLeast "2.6"; then + return 1 + fi + + # DCO is built into Linux 6.16+, or available via ovpn-dco module + if kernelVersionAtLeast "6.16"; then + return 0 + elif lsmod 2>/dev/null | grep -q "^ovpn_dco" || modinfo ovpn-dco &>/dev/null; then + return 0 + fi + return 1 +} + function installOpenVPNRepo() { log_info "Setting up official OpenVPN repository..." @@ -975,6 +1011,18 @@ function installOpenVPN() { log_info "OpenVPN version supports ChaCha20-Poly1305" fi + # Check Data Channel Offload (DCO) availability + if isDCOAvailable; then + # Check if configuration is DCO-compatible + if [[ $PROTOCOL == "udp" ]] && [[ $COMPRESSION_ENABLED == "n" ]] && [[ $CIPHER =~ (GCM|CHACHA20-POLY1305) ]]; then + log_info "Data Channel Offload (DCO) is available and will be used for improved performance" + else + log_info "Data Channel Offload (DCO) is available but not enabled (requires UDP, AEAD cipher, no compression)" + fi + else + log_info "Data Channel Offload (DCO) is not available (requires OpenVPN 2.6+ and kernel support)" + fi + # An old version of easy-rsa was available by default in some openvpn packages if [[ -d /etc/openvpn/easy-rsa/ ]]; then run_cmd "Removing old Easy-RSA" rm -rf /etc/openvpn/easy-rsa/