OpenVPN
OpenVPN's network protocol

Description of packet structure in OpenVPN's network protocol.

This document describes the structure of packets exchanged between OpenVPN peers. It is based on the protocol description in the ssl.h file.

Outer structure of packets exchanged between OpenVPN peers

VPN tunnel packets are transported between OpenVPN peers using the UDP or TCP protocols. Their structure is described below.

External packet structure

  • packet length (16 bits, unsigned) [TCP-mode only]: always sent as plain text. Since TCP is a stream protocol, this packet length defines the packetization of the stream.
  • packet opcode and key_id (8 bits) [TLS-mode only]:
    • package message type (high 5 bits)
    • key_id (low 3 bits): the key_id refers to an already negotiated TLS session. OpenVPN seamlessly renegotiates the TLS session by using a new key_id for the new session. Overlap (controlled by user definable parameters) between old and new TLS sessions is allowed, providing a seamless transition during tunnel operation.
  • payload (n bytes)

Message types

The type of a VPN tunnel packet is indicated by its opcode. The following describes the various opcodes available.

Session IDs and Key IDs

OpenVPN uses two different forms of packet identifiers:

  • The first form is 64 bits and is used for all control channel messages. This form is referred to as a session_id.
  • Data channel messages on the other hand use a shortened form of 3 bits for efficiency reasons since the vast majority of OpenVPN packets in an active tunnel will be data channel messages. This form is referred to as a key_id.

The control and data channels use independent packet-id sequences, because the data channel is an unreliable channel while the control channel is a reliable channel. Each use their own independent HMAC keys.

Control channel reliability layer

Control channel messages (P_CONTROL_* and P_ACK_* message types) are TLS ciphertext packets which have been encapsulated inside of a reliability layer. The reliability layer is implemented as a straightforward acknowledge and retransmit model.

Acknowledgments of received messages can be encoded in either the dedicated P_ACK_* record or they can be prepended to a P_CONTROL_* message.

See the Reliability Layer module for a detailed description.

Structure of control channel messages

Structure of ciphertext control channel messages

Control channel packets in ciphertext form consist of the following parts:

  • local session_id (random 64 bit value to identify TLS session). (the tls-server side uses a HMAC of the client to create a pseudo random number for a SYN Cookie like approach)
  • HMAC signature of entire encapsulation header for HMAC firewall [only if –tls-auth is specified] (usually 16 or 20 bytes).
  • packet-id for replay protection (4 or 8 bytes, includes sequence number and optional time_t timestamp).
  • acknowledgment packet-id array length (1 byte).
  • acknowledgment packet-id array (if length > 0).
  • acknowledgment remote session-id (if length > 0).
  • packet-id of this message (4 bytes).
  • TLS payload ciphertext (n bytes) (only for P_CONTROL_V1).

Note that when –tls-auth is used, all message types are protected with an HMAC signature, even the initial packets of the TLS handshake. This makes it easy for OpenVPN to throw away bogus packets quickly, without wasting resources on attempting a TLS handshake which will ultimately fail.

Control channel key methods

Once the TLS session has been initialized and authenticated, the TLS channel is used to exchange random key material for bidirectional cipher and HMAC keys which will be used to secure data channel packets. OpenVPN currently implements two key methods. Key method 1 directly derives keys using random bits obtained from the rand_bytes() function. Key method 2 mixes random key material from both sides of the connection using the TLS PRF mixing function. Key method 2 is the preferred method and is the default for OpenVPN 2.0+.

The Data channel key generation related page describes the key methods in more detail.

Structure of plaintext control channel messages

  • Key method 1 (support removed in OpenVPN 2.5):
    • Cipher key length in bytes (1 byte).
    • Cipher key (n bytes).
    • HMAC key length in bytes (1 byte).
    • HMAC key (n bytes).
    • Options string (n bytes, null terminated, client/server options string should match).
  • Key method 2:
    • Literal 0 (4 bytes).
    • Key method (1 byte).
    • key_source structure (key_source.pre_master only defined for client -> server).
    • Options string length, including null (2 bytes).
    • Options string (n bytes, null terminated, client/server options string must match).
    • [The username/password data below is optional, record can end at this point.]
    • Username string length, including null (2 bytes).
    • Username string (n bytes, null terminated).
    • Password string length, including null (2 bytes).
    • Password string (n bytes, null terminated).

Structure of data channel messages

The P_DATA_* payload represents encapsulated tunnel packets which tend to be either IP packets or Ethernet frames. This is essentially the "payload" of the VPN. Data channel packets consist of a data channel header, and a payload. There are two possible formats:

P_DATA_V1
P_DATA_V1 packets have a 1-byte header, carrying the P_DATA_V1 opcode and key_id, followed by the payload:
[ 5-bit opcode | 3-bit key_id ] [ payload ]
P_DATA_V2
P_DATA_V2 packets have the same 1-byte opcode/key_id, but carrying the P_DATA_V2 opcode, followed by a 3-byte peer-id, which uniquely identifies the peer:
[ 5-bit opcode | 3-bit key_id ] [ 24-bit peer-id ] [ payload ]

See Data Channel Crypto module for details on the data channel payload format.