Skip to main content

Overview

OpenVPN uses different ciphers for the control channel (TLS) and data channel (VPN traffic). This guide focuses on data channel cipher configuration and negotiation.

Cipher negotiation

OpenVPN 2.4 and later support automatic cipher negotiation between client and server.

How negotiation works

When both client and server are OpenVPN 2.5 or later:
1

Client announces supported ciphers

The client sends its list of supported ciphers from --data-ciphers to the server.
2

Server selects cipher

The server picks the first cipher from its --data-ciphers list that is also supported by the client.
3

Cipher confirmed

The selected cipher is used for encrypting all data channel traffic.
4

Connection rejected if no match

If no common cipher is found, the client receives:
AUTH_FAILED,Data channel cipher negotiation failed (no shared cipher)

Data cipher configuration

Default ciphers

OpenVPN 2.5:
# Default data-ciphers
AES-256-GCM:AES-128-GCM
OpenVPN 2.6 and later:
# Default data-ciphers (when Chacha20-Poly1305 available)
AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

Setting data ciphers

# Server configuration
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
The server’s cipher order takes precedence. The first cipher in the server’s list that is also in the client’s list will be selected.

Viewing available ciphers

# Show all data channel ciphers
openvpn --show-ciphers

# Example output:
AES-256-GCM
AES-128-GCM
AES-256-CBC
AES-128-CBC
CHACHA20-POLY1305
BF-CBC

Modern secure ciphers (AEAD)

AEAD (Authenticated Encryption with Associated Data) ciphers provide both encryption and authentication:
CipherKey SizePerformanceSecurityRecommendation
AES-256-GCM256-bitExcellent with AES-NIExcellentRecommended
AES-128-GCM128-bitExcellent with AES-NIExcellentRecommended
CHACHA20-POLY1305256-bitExcellent on mobileExcellentRecommended
AEAD ciphers don’t use the --auth option. Authentication is built into the cipher.

Legacy ciphers (CBC mode)

CBC mode ciphers are less secure than AEAD ciphers and should only be used for compatibility with older clients.
CipherKey SizeSecurityStatus
AES-256-CBC256-bitGood (with auth)Legacy
AES-128-CBC128-bitGood (with auth)Legacy
BF-CBC (Blowfish)128-bitWeakDeprecated
DES-CBC56-bitBrokenInsecure

Cipher recommendations by use case

# Servers with hardware AES support
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

Cipher configuration options

data-ciphers (preferred method)

Specifies the list of allowed data channel ciphers for negotiation:
# Set allowed ciphers
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

cipher (fallback method)

Specifies a single cipher for non-negotiating clients:
# Fallback cipher for old clients
cipher AES-256-CBC
In OpenVPN 2.5+ with --compat-mode 2.4.x or lower, the --cipher value is automatically added to --data-ciphers for backwards compatibility.

data-ciphers-fallback

Specifies the cipher to use when negotiation fails:
# Fallback for clients configured with --enable-small
data-ciphers-fallback AES-256-CBC
Only use --data-ciphers-fallback when supporting very old clients (OpenVPN 2.3 or earlier) compiled with --enable-small.

Authentication configuration

For CBC mode ciphers

CBC mode ciphers require a separate HMAC authentication:
# Set authentication algorithm
auth SHA256

# Or stronger
auth SHA512

Viewing available digests

# Show available HMAC algorithms
openvpn --show-digests

# Example output:
SHA1
SHA256
SHA384
SHA512
MD5 (insecure)
AlgorithmOutput SizeSecurityStatus
SHA512512-bitExcellentRecommended
SHA384384-bitExcellentRecommended
SHA256256-bitExcellentRecommended
SHA1160-bitWeakDeprecated
MD5128-bitBrokenInsecure
For AEAD ciphers (GCM, CHACHA20-POLY1305), the --auth option is ignored as authentication is built into the cipher.

Backward compatibility

Supporting OpenVPN 2.4 clients

OpenVPN 2.4 clients announce support for AES-256-GCM and AES-128-GCM by default:
# Server configuration to support 2.4 clients
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC

# Fallback for very old clients
cipher AES-256-CBC
auth SHA256

Supporting OpenVPN 2.3 clients

Older clients without negotiation support:
# Server must include client's cipher in data-ciphers
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC:BF-CBC

# Match client's configured cipher
cipher AES-256-CBC
auth SHA256

Supporting OpenVPN 3 clients

OpenVPN 3-based clients (mobile apps):
# Server configuration
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
OpenVPN 3 clients always announce support for all AEAD ciphers and may disable legacy CBC ciphers.

Cipher negotiation scenarios

Example 1: Modern setup

data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
Result: AES-256-GCM is selected (first match in server’s list).

Example 2: Mixed environment

data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC
cipher AES-256-CBC
auth SHA256
Result:
  • Modern client uses AES-256-GCM (negotiated)
  • Legacy client uses AES-256-CBC (fallback)

Example 3: No common cipher

data-ciphers AES-256-GCM:AES-128-GCM
Result: Connection rejected with AUTH_FAILED,Data channel cipher negotiation failed.

Blowfish deprecation

Blowfish (BF-CBC) was the default cipher in OpenVPN 2.4 and earlier.
Blowfish is cryptographically weak and should not be used. OpenVPN 2.5+ does not allow BF-CBC unless explicitly configured.

Migrating from Blowfish

1

Update server configuration

# Add modern ciphers while keeping BF-CBC temporarily
data-ciphers AES-256-GCM:AES-128-GCM:BF-CBC
cipher BF-CBC
auth SHA256
2

Update client configurations gradually

# New client configuration
data-ciphers AES-256-GCM:AES-128-GCM
3

Remove BF-CBC from server

Once all clients are updated:
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

Performance considerations

Hardware acceleration

Check if your CPU supports AES-NI:
# Check for AES-NI support
grep -o 'aes' /proc/cpuinfo | head -1

# Or more detailed
lscpu | grep -i aes

Cipher performance comparison

CipherWith AES-NIWithout AES-NIMobile
AES-256-GCMExcellentGoodGood
AES-128-GCMExcellentGoodGood
CHACHA20-POLY1305GoodGoodExcellent
AES-256-CBCVery GoodFairFair
On systems with AES-NI hardware acceleration, AES-GCM ciphers typically outperform CHACHA20-POLY1305. On mobile devices without AES-NI, CHACHA20-POLY1305 often performs better.

Benchmarking ciphers

# OpenSSL speed test
openssl speed aes-256-gcm aes-128-gcm chacha20-poly1305

# Test specific cipher performance
openssl speed -evp aes-256-gcm

Packet format and overhead

AEAD cipher packet format

[ Opcode/Key-ID ] [ Packet ID ] [ Auth Tag ] [ Encrypted Payload ]
      1 byte          4 bytes       16 bytes       Variable

CBC cipher packet format

[ HMAC ] [ IV ] [ Packet ID ] [ Encrypted Payload ]
 20-64    16         4              Variable
 bytes   bytes     bytes

Overhead calculation

For AEAD ciphers:
  • Opcode: 1 byte
  • Packet ID: 4 bytes
  • Auth Tag: 16 bytes
  • Total overhead: 21 bytes
For CBC ciphers:
  • HMAC: 20-64 bytes (depends on --auth)
  • IV: 16 bytes
  • Packet ID: 4 bytes
  • Total overhead: 40-84 bytes

Advanced configuration

Disabling cipher negotiation

# Force specific cipher without negotiation (not recommended)
ncp-disable
cipher AES-256-GCM
Disabling NCP (cipher negotiation) prevents automatic cipher selection and reduces security flexibility.

Compatibility mode

# Emulate OpenVPN 2.4 behavior
compat-mode 2.4.x

Testing cipher configuration

# Test configuration syntax
openvpn --config test.conf --show-ciphers

# Verify negotiated cipher in logs
openvpn --config server.conf --verb 4 | grep -i cipher

Security best practices

  1. Use only AEAD ciphers - AES-GCM and CHACHA20-POLY1305 provide best security
  2. Prioritize by security - List strongest ciphers first in --data-ciphers
  3. Avoid deprecated ciphers - Do not use BF-CBC, DES, or 3DES
  4. Remove CBC mode - Transition to AEAD-only when possible
  5. Regular updates - Keep OpenVPN updated to support latest ciphers
  6. Test thoroughly - Verify cipher negotiation works before deploying
  7. Monitor logs - Check which ciphers are actually being used
  8. Document exceptions - If supporting legacy ciphers, document why and when to remove

Troubleshooting

No shared cipher error

Error message:
AUTH_FAILED,Data channel cipher negotiation failed (no shared cipher)
Solutions:
  • Add common cipher to both client and server --data-ciphers
  • Check cipher availability with openvpn --show-ciphers
  • Verify crypto library versions support the same ciphers

Cipher not available

Error message:
Cipher algorithm 'CHACHA20-POLY1305' not found
Solutions:
# Check OpenSSL version (needs 1.1.0+)
openssl version

# Check cipher availability
openssl list -cipher-algorithms | grep -i chacha

# Upgrade OpenSSL if needed
apt-get update && apt-get upgrade openssl

Performance issues

# Check CPU features
lscpu | grep -i flags | grep aes

# Monitor CPU usage
top -p $(pgrep openvpn)

# Consider different cipher
# With AES-NI: prefer AES-GCM
# Without AES-NI: prefer CHACHA20-POLY1305

Verify active cipher

# Check OpenVPN logs
grep -i "data channel cipher" /var/log/openvpn.log

# Or increase verbosity
openvpn --config client.conf --verb 4 | grep -i cipher

Migration guide

From legacy to modern ciphers

1

Audit current configuration

# Check current cipher
grep -E "cipher|data-ciphers" /etc/openvpn/*.conf
2

Update server first

# Add modern ciphers while keeping legacy
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC
cipher AES-256-CBC
auth SHA256
3

Update clients gradually

# Modern client configuration
data-ciphers AES-256-GCM:AES-128-GCM
4

Remove legacy ciphers

After all clients updated:
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
# Remove cipher and auth lines
5

Verify

# Check logs for cipher usage
grep "Data Channel" /var/log/openvpn.log

Build docs developers (and LLMs) love