Internet-Draft | OpenVPN Wire Protocol | January 2038 |
Schwabe, et al. | Expires 23 July 2038 | [Page] |
OpenVPN is an open source SSL/TLS based VPN solution which had its first release in May 2001. This document describes the wire protocol OpenVPN makes use of for establishing end-to-end- connections. Even though OpenVPN bases its communication on SSL/TLS, it is not a traditional SSL/TLS protocol which utilizes only TCP. OpenVPN supports some enhanced security features as well as providing SSL/TLS connections both over TCP as well as UDP. This document focuses on the modern/current variant of the OpenVPN protocol. Some of the features used in older variants of the protocol are not documented.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 23 July 2038.¶
Copyright (c) 2038 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Please not that this document is work in progress and should not considered a complete or correct documentation of the OpenVPN protocol yet. Please check the current implementations.¶
OpenVPN is an open source SSL/TLS based VPN solution which was first released in 2001. The communication between OpenVPN instances are based on SSL/TLS but it has added several additional features on top of the standard SSL/TLS protocol. The wire protocol this document describes will go into the depths of how OpenVPN processes communicates with each other.¶
The wire protocol is dynamic, which means it will be slightly different depending on which features the OpenVPN processes have been configured to use. New implementations SHOULD implement all features.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119].¶
Since OpenVPN can work both in a traditional server-client setup as well as a peer-to-peer setup, this document tries to avoid the concept of server and clients. It will refer to these as either the local or remote sites. In a peer-to-peer setup only a single tunnel can be established, while in a server-client setup several clients can connect to a single server at the same time. If the terms server and client are used these are almost always synonymous with the peer's role as either TLS server or TLS client.¶
OpenVPN is capable of using both UDP and TCP for transporting SSL/TLS traffic. The SSL/TLS protocol is strictly written for TCP but OpenVPN makes that possible through encapsulating the SSL/TLS packets and adding a reliability layer to avoid issues when packets get resent.¶
The OpenVPN protocol has a mode where it does not use dynamic key derivation but instead uses static keys. The mode does not make use of any TLS features, so it is called static key mode. In this mode there is no control channel and all the data on the wire is plain encrypted packets transported over a standard UDP or TCP connection.¶
Peer-to-peer mode also depends on a shared secret key between both ends of the VPN tunnel. Again, as there are no SSL/TLS handshakes between either side, this method does not have any possibilities to enable Perfect Forward Secrecy (PFS). The data channel is encrypted solely by the shared static secret. This mode does not negotiate any ephemeral session keys for the tunneled data. Using pre-shared secrets also significantly weakens the guarantees for no IV reuse, so modern ciphers like AES in GCM mode are not available in this mode. This mode is deprecated and this document does not provide documentation for it.¶
With TLS mode the control channel gets activated and this requires both sides to make use of private keys and X.509 [RFC5280] Certificates. These requirements are due to this operational mode utilizing the TLS/SSL [RFC5246] protocol. This mode is also the only operational mode which uses the client-server terminology in OpenVPN.¶
The use of X.509 certificates on the client side is OPTIONAL and is REQUIRED on the server side. It is highly RECOMMENDED to always enable user/password authentication when X.509 client certificates are not used.¶
It is highly RECOMMENDED to enforce certificate authentication against a locally controlled Certificate Authority (CA) certificate. The use of public Certification Authorities will reduce the security of the tunnel dramatically, as it can easily enable man-in-the-middle attacks where the client cannot verify the true identity of a server, or a server cannot verify the true identity of a client.¶
[FIXME/syzzer: explain more what happens on the wire during the SSL/TLS handshake and certificate authentication]¶
The TLS mode will use the same communication channel for both TLS handshakes and the tunnel data. The TLS handshakes are referred to as the control channel and tunnel data is referred to as the data channel. Each packet in TLS mode contains an OPCODE which defines if the following payload is a control channel or data channel packet.¶
OpenVPN uses a single UDP or TCP connection between two peers. Over this connection all packets for the VPN connection are multiplexed. In UDP one packet is is the same as one UDP payload. When TCP is used, each packet with started by a 16 bit length indicator in network byte order, followed by the packet.¶
Each packet starts with an opcode that determines the packet type. OpenVPN packets fall can be differentiated into two types of packets: control channel packets and data channel apckets. They share the same header but serve different purposes. The data channel packets transport the VPN payload, typically IP packets. The control channel packets are used to setup and control the VPN connection.¶
The key_id specifies a key generation that allow to multiplex different key generations.¶
struct tcp_packet { uint16 len; int opcode:5; int keyid:3; uint8 data[]; } struct udp_packet { int opcode:5; int keyid:3; uint8 data[]; }¶
The following sections will often only show the UDP format for brievity. The TCP format can be infered by prepending the 16 bit length field.¶
The data channel section (Section 7) and control channel (Section 6) sections describe the formats of the packets in details.¶
There are three different variants of the control channel format. The format depends on the variant of control channel authentication and encryption.¶
struct control_packet { int opcode:5; int keyid:3; uint64_t own_session_id; uint8_t acked_pktid_len; uint8_t[n*8] acked_pktid_list; [only if acked_id_len > 0] uint64_t peer_session_id; [only if acked_id_len > 0] uint32_t packet_id; uint8_t control_channel_payload[]; }¶
The basic form of control channe ldoes not involve any additional authentication or encryption of control channel packets.¶
The own_session_id
is an opaque id that identifies the session id
from the perspective of the peer. The peer MUST NOT make any assumption about the
format of this id. It is RECOMMEND to use 64 bit of randomness.¶
The replay_packet_id
64 bit counter that is used by both tls-crypt and tls-auth has internally
the following format¶
struct replay_packet_id_packet { uint32_t packet_id; uint32_t timestamp; }¶
This format is a legacy from old static key mode from OpenVPN to avoid IV reuse and provide a stable packet counter. While OpenVPN largely abondoned this format and static key format, this packet counter format still survived in the replay protection for tls-auth and tls-crypt protocol. Unfortunately, in this format the format the order of the fields does not represent their significance and when interpreting this as a 64bit counter, the timestamp value represents the more significant bytes. To turn this structure into a 64bit counter, the timestamp represent the upper 32 bit while the packet_id represents the lower 32 bits. (timestamp << 32) | packet_id¶
struct tlsauth_control { int opcode:5; int keyid:3; uint64_t own session_id; uint8[8-32] hmac; uint64_t replay_packet_id; uint8_t acked_pktid_len; uint8_t[n*8] acked_pktid_list; [only if acked_id_len > 0] uint64_t peer_session_id; [only if acked_id_len > 0] uint32_t packet_id; uint8_t payload[]; }¶
In this mode, which is also called tls-auth in existing implementations, control channel packets are authenticated by the use of an HMAC [RFC2104] signature using a pre-shared key.¶
This authentication can strengthen the overall security on both client and server side as OpenVPN will validate the HMAC signature before any other processing on the packet is done. This can protect server and client from triggering problems in other parts of implementation such as TLS protocol implementations.¶
The keys used for the HMAC signatures are static and pre-shared between server and all clients. The default hashing algorithm is HMAC-SHA1 but any hashing algorithms supported by the SSL/TLS protocol can be used as long as the clients and server are configured to use the same algorithm. The choice of hashing algorithms defines the length of the HMAC field in the control packet. HMAC-SHA1 uses 160 bits (20 bytes), HMAC-SHA512 uses 512 bits (64 bytes).¶
The key used for the HMAC signatures has the same length as the HAMC signature. A different key is used for each direction between two peers. The keys can be identical but it is recomended that they are different. The appendix OpenVPN static key format (Section 11.1) will provide the file format that is used in existing implementations to provide these keys.¶
The HMAC is calculated over the following pseudo packet, which moves the replay_packet_id to the beginning and drops the hmac field.¶
struct tlsauth_control { uint64_t replay_packet_id; int opcode:5; int keyid:3; uint64_t own session_id; uint8_t acked_pktid_len; uint8_t[n*8] acked_pktid_list; [only if acked_id_len > 0] uint64_t peer_session_id; [only if acked_id_len > 0] uint32_t packet_id; uint8_t payload[]; }¶
When sending or resending a packet, an implementation must increase the replay_packet_id counter, calculate the HMAC and send the packet with the HMAC.¶
On recieving, the receiver MUST check if the replay_packet_id is not an already received replay_packet_id or is lower by 32 or more than the highest replay_packet_id in an authenticated packet from a peer and otherwise discard it. The value 32 MAY be configurable. If the packet passes this test, the HMAC of the packet using the outlined procedure MUST be calculated and verfied. If the HMAC does not match, the implementation MUST discard the packet.¶
When using this format of control packets, OpenVPN peers will encrypt the control
packet channel payload using pre-shared static keys. The encryption scheme uses
a pair of encryption key Ke
(256 bite) and HMAC authentication key Ka
(256 bits) per direction, four private keys or 1024 bits in total.
In existing impelmentation this feature is usually referred to as "tls-crypt".¶
Encrypting control channel packets has three main advantages:¶
The encryption method is based on the SIV construction [rogaway2006provable], to achieve nonce misuse-resistant authenticated encryption. Note that this is is using AES256-CTR and HMAC-SHA256 and is not the RFC8452 AES-GCM-SIV [RFC8452].¶
TODO: Check if our scheme is one that is described in RFC 5297¶
The use of a nonce misuse-resistant authenticated encryption scheme allows minimising the risks of nonce collisions. This is important, because in contrast to other encryption as TLS, it is impractical to rotate the pre-shared keys often or fully guarantee nonce uniqueness. For non misuse-resistant modes such as GCM ([ferguson2005authentication], [joux2006authentication]), the TLS (or OpenVPN's own data channel) only has to ensure that the packet counter never rolls over, while the encryption of control packages would have to provide nonce uniqueness over all control channel packets sent by all clients, for the lifetime of the pre-shared key.¶
This control channel packet format uses fixed encryption and authentication algorithms. This encryption intention is to primarely provide privacy as well as DoS protection, these MUST not be made negotiable.¶
The format of a tls-crypt control packet looks are the following:¶
struct tlscrypt_control { int opcode:5; int keyid:3; uint64_t own session_id; uint64_t replay_packet_id; uint8 auth_tag[32]; uint8[] enc_control_payload; }¶
The encrypted payload enc_control_payload consits of encrypting the following structure:¶
struct clear_control_payload { uint8_t acked_pktid_len; uint8_t[n*8] acked_pktid_list; [only if acked_id_len > 0] uint64_t peer_session_id; [only if acked_id_len > 0] uint32_t packet_id; uint8_t control_channel_payload[]; }¶
The auth tag is generated by generating a HMAC-SHA256 with the pre-shared HMAC key over the the cleartext of the tls_auth_control structure and the clear_control_payload struct, omitting the auth_tagfand enc_control_payload fields:¶
auth_tag = HMAC-SHA256(Ka, opcode || keyid || own_session_id || replay_packet_id || clear_control_payload)
¶
Using the auth_tag, we create the IV from it.¶
IV = 128 most-significant bits of auth_tag
¶
And finally the enc_control_payload
is encrypted using AES-CTR with Ke
as key and the constructed IV:¶
enc_control_payload = AES256-CTR(Ke, IV, clear_control_payload)
¶
This encryption scheme is a best-effort mechanism aiming to provide as much privacy and security as possible, while staying as simple as possible. The following are some security considerations for this scheme.¶
The same set of pre-shared key is potentially shared by a lot of peers, so it is quite likely to get compromised. Once an attacker acquires the tls-crypt key, this mechanism no longer provides any security against the attacker.¶
Since many peers potentially use the same set of keys for a long time, a lot of data might be encrypted under the encryption keys. This leads to two potential problems:¶
The opcode || session id || packet id
combination might collide.
This might happen in larger setups, because the session id contains
just 64 bits of randomess. Using the uniqueness requirement from the
GCM spec [nistgcm]
(a collision probability of less than 2^(-32)),
uniqueness is achieved when using the tls-crypt key for at most
2^16 (65536) connections per process start. (The packet id
includes the daemon start time in the packet ID, which should be
different after stopping and (re)starting OpenVPN.)¶
And if a collision happens, an attacker can *only* learn whether colliding packets contain the same plaintext. Attackers will not be able to learn anything else about the plaintext (unless the attacker knows the plaintext of one of these packets, of course). Since the impact is limited, this is considered an acceptable remaining risk.¶
Typical OpenVPN implementations will use the same key format as for the authentication of control channel to distribute the pre-shared keys. See Appendix OpenVPN static key format (Section 11.1) for a description of the format.¶
This section describes configuring OpenVPN to use client-specific tls-crypt keys. This feature is referred to as tls-crypt-v2 in existing implementations.¶
``--tls-auth`` and ``tls-crypt`` use a pre-shared group key, which is shared among all clients and servers in an OpenVPN deployment. If any client or server is compromised, the attacker will have access to this shared key, and it will no longer provide any security. To reduce the risk of losing pre-shared keys, ``tls-crypt-v2`` adds the ability to supply each client with a unique tls-crypt key. This allows large organizations and VPN providers to profit from the same DoS and TLS stack protection that small deployments can already achieve using ``tls-auth`` or ``tls-crypt``.¶
Also, for ``tls-crypt``, even if all these peers succeed in keeping the key secret, the key lifetime is limited to roughly 8000 years, divided by the number of clients (see the ``--tls-crypt`` section of the man page). [FIXME/flichtenheld: either include or remove reference] Using client-specific keys, we lift this lifetime requirement to roughly 8000 years for each client key (which "Should Be Enough For Everybody (tm)").¶
The per client encryption key schema uses an encrypted cookie mechanism to introduce client-specific tls-crypt keys without introducing a lot of server-side state. The client-specific key is encrypted using a server key. The server key is the same for all servers in a group. When a client connects, it first sends the encrypted key to the server, such that the server can decrypt the key and all messages can thereafter be encrypted using the client-specific key.¶
A wrapped (encrypted and authenticated) client-specific key can also contain metadata. The metadata is wrapped together with the key, and can be used to allow servers to identify clients and/or key validity. This allows the server to abort the connection immediately after receiving the first packet, rather than performing an entire TLS handshake. Aborting the connection this early greatly improves the DoS resilience and reduces attack surface against malicious clients that have the ``tls-crypt`` or ``tls-auth`` key. This is particularly relevant for large deployments (think lost key or disgruntled employee) and VPN providers (clients are not trusted).¶
To allow for a smooth transition, this feature is designed such that a server can enable both the per client encryption and either ``tls-crypt`` or ``tls-auth``. This is achieved by introducing a CONTROL_HARD_RESET_CLIENT_V3 opcode, that indicates that the client wants to use ``tls-crypt-v2`` for the current connection.¶
This implementation here assumes that all server share the same pre-shared key. Since the server implementation is transparent to the client, another schema can be potentially used.¶
The server key cosists of 2 512-bit keys, of which we use:¶
The client key consists of two parts. The client-specific key ``Kc`` and a wrapped key ``WKc`` that is opaque to the client.¶
The 2048 bits client-specific key ``Kc`` is identical to the key for the control channel encryption.¶
The standard format used by OpenVPN for the wrapped key has the foloowing components:¶
Optional Metadata The first byte of the metadata determines the type. The initial implementation supports the following types:¶
The timestamp can be used to reject too-old tls-crypt-v2 client keys.¶
User metadata could for example contain the users certificate serial, such that the incoming connection can be verified against a CRL.¶
If no metadata is supplied during key generation, an implementation SHOULD default to the TIMESTAMP metadata type.¶
Create a wrapped client key ``WKc``, using the same nonce-misuse-resistant SIV construction we use for tls-crypt:¶
len = len(WKc) (16 bit, network byte order) T = HMAC-SHA256(Ka, len || Kc || metadata) IV = 128 most significant bits of T WKc = T || AES-256-CTR(Ke, IV, Kc || metadata) || len¶
Note that the length of ``WKc`` can be computed before composing ``WKc``, because the length of each component is known (and AES-256-CTR does not add any padding).¶
-----BEGIN OpenVPN tls-crypt-v2 client key-----
and the footer -----END OpenVPN tls-crypt-v2 client key-----
. (The PEM
format is simple, and following PEM allows us to use the crypto library functions
for en/decoding.)¶
Note, since the Wkc format is opaque to the client, a server can decide to use a different format. For example when using a large infrastructure, e.g. a Cloud service, it is desirable to allow using multiple different server keys to be able to replace a compromised key or to be able to do key rotation.¶
In this scenario a cleartext key id should be added to allow the server to select the key that should be used to decrypt the wrapped key.¶
As example how to implement this wrapping, assume the server keys are using a 32 bit index. The server key (Ke, Ka) with the index i is named Kai and Kei.¶
K_id = key id of server key Kai, Kei (32 bit, network order) len = len(WKc) (16 bit, network byte order) T = HMAC-SHA256(Kai, len || K_id || Kc || metadata) IV = 128 most significant bits of T WKc = T || AES-256-CTR(Ke, IV, Kc || metadata) || K_id || len¶
When setting up the OpenVPN connection:¶
The client reads the tls-crypt-v2 key from its config, and:¶
The server receives the P_CONTROL_HARD_RESET_CLIENT_V3 message, and¶
The message is dropped and no error response is sent when any of these steps fails (DoS protection).¶
Setting up connection with cookie support To avoid exhaustion attack and keeping state for connections that fail to complete the three way handshake, the OpenVPN server will use its own session id as challenge that the client must repeat in the third packet of the handshake. This introduces a problem. If the server does not keep the wrapped client key from the initial packet, the server cannot decode the third packet. Therefore, tls-crypt-v2 allows resending the wrapped key in the third packet of the handshake with the P_CONTROL_WKC_V1 message. The modified handshake is as follows (the rest of the handshake is unmodified):¶
To allow for a smooth transition, the server implementation allows ``tls-crypt`` or ``tls-auth`` to be used simultaneously with ``tls-crypt-v2``. This specification does not allow simultaneously using ``tls-crypt-v2`` and connections without any control channel wrapping, because that would break DoS resilience.¶
WKc includes a length field, so we leave the option for future extension of the P_CONTROL_HEAD_RESET_CLIENT_V3 message open. (E.g. add payload to the reset to indicate low-level protocol features.)¶
``tls-crypt-v2`` uses fixed crypto algorithms, because:¶
Potential ``tls-crypt-v2`` risks:¶
OpenVPN communicates over two channels which are multiplexed over the same connection; control channel and data channel. The control channel is used for passing configuration and environment data between each side of the tunnel, including encryption session keys. The data channel carries the encrypted tunnel data. The OPCODE determines which channel the packet belongs to.¶
Each packet MUST contain an OPCODE. This is located within the first byte in each UDP packet and the third byte in TCP packets. The high 5 bits contains the OPCODE and the lower 3 bits defines a key-id. The OPCODE defines the contents of the following payload. The op codes DATA_V1 and DATA_V2 are NOT control channel op coes and will NOT be discussed in this chapter. They are included for completeness.¶
OPCODE | Channel | Short name | Payload | Status |
---|---|---|---|---|
1 | Control | CONTROL_HARD_RESET_CLIENT_V1 | Obsolete | |
2 | Control | CONTROL_HARD_RESET_SERVER_V1 | Obsolete | |
3 | Control | CONTROL_SOFT_RESET_V1 | - | Obsolete |
4 | Control | CONTROL_V1 | X | Current |
5 | Control | ACK_V1 | X | Current |
6 | Data | DATA_V1 | X | Current |
7 | Control | CONTROL_HARD_RESET_CLIENT_V2 | - | Current |
8 | Control | CONTROL_HARD_RESET_SERVER_V2 | - | Current |
9 | Data | DATA_V2 | X | Current |
10 | Control | CONTROL_HARD_RESET_CLIENT_V3 | X | Current |
11 | Control | CONTROL_WKC_V1 | X | Current |
The control channel is used to pass configuration and environment information in addition to handle the SSL/TLS handshake process between the server and client.¶
The following table lists all fields found in control channel packets. The fields arrive in the order they are listed in the table.¶
The TLS auth column indicates fields used when additional HMAC authentication data is added to the control channel packets.¶
Field name | Length (bits) | TLS auth | Comment |
---|---|---|---|
pkt_len | 16 | Packet length (TCP only) | |
OPCODE | 5 | ||
key_id | 3 | X | |
own session_id | 64 | X | |
HMAC | 128-512 | X | Algorithm defines length |
replay_packet_id | 64 | X | ID used for replay protection. |
acked_pktid_len | 8 | X | |
acked_pktid_list | 32 * n | X | List length defined by acked_pktid_len. |
peer session id | 64 | X | Session ID of the remote peer. Present if acked_pktid_len >= 1 |
packet_id | 32 | X | ID of the control channel packet. ACK packets lack a packet_id |
payload | (var) | X | Can be empty |
This field is only present when TCP is used as the transport protocol. This value should be the number of bytes being transported in this packet, excluding the pkt_len field.¶
The OPCODE field is described in detail in the Control Channel OPCODEs (Section 6.2.2) section.¶
This is used to indicate which keys to use when processing the payload. This has a range from 0 to 7. All new sessions starts with key_id 0. After a key renegotiation the key_id will increase by one. After key_id 7, the key_id wraps to 1.¶
This is a unique random value for a particular connected session. If an established session needs a full reconnect, the session ID MUST be changed. Client and server have their own independent session ID.¶
Contains the HMAC signature for this packet if the HMAC authentication has been enabled. The length of this field will vary according to the requirements of the hashing algorithm.¶
This is an incremental ID for each packet which helps discovering packet replay attacks. Usually consists of a 32 bit time + 32 bit counter but can be any monotonically increasing sequence. For both fields the value is transferred using network byte order.¶
For CFB/OFB based ciphers, the long packet_id format MUST be used, as the packet_id is part of the cipher's IV. [FIXME/syzzer: Elaborate more] [FIXME/schwabe: move to data channel]¶
Defines the number of acked packet IDs being reported in this packet. If set to 0, no acked packet ID elements will be found, otherwise the following 4 bytes * acked_pktid_len of data will contain the list of acked packet IDs.¶
This field contains the packet ID which the remote side have received and processed. This field will appear up to acked_pktid_len number of times, each with an individual packet ID. These packet IDs should be found in a local cache of sent packet IDs. If not found, the communication may have been manipulated.¶
If acked_pktid_len is 1 or greater this field MUST be present and specify the remote session id. If acked_pktid_len is 0 the field MUST be absent.¶
The ID of the control channel packet. The packet IDs are used to ensure a TCP-like connection even if UDP is used as protocol. The ID MUST start at 0 and MUST be sequential without gaps. Retransmission must have the same packet_id as the original message but can have a different replay_packet_id. ACK packages MUST NOT have a packet_id.¶
The payload to be processed. This is most commonly an encrypted blob which is expected to be passed on to the SSL/TLS library for further processing. [FIXME: Elaborate more]¶
OBSOLETE: This OPCODE is not in use any more.¶
This MAY be reused in the future once all other OPCODE slots are in use.¶
OBSOLETE: This OPCODE is not in use any more.¶
This MAY be reused in the future once all other OPCODE slots are in use.¶
Start new TLS session to generate a new data channel key to allow a graceful transition from old to new key.¶
This is used to rotate session keys. It allows both a new key and the old ones to be valid for a limited transition window. The transition window size is decided by the server. This window SHOULD NOT exceed the expected renegotiation cycle.¶
Either client or server MAY send a CONTROL_SOFT_RESET_V1 packet to the remote side. The remote side MUST respond with a CONTROL_SOFT_RESET_V1 message to acknowledge that a renegotiation of the session keys will start. Then the side receiving the last CONTROL_SOFT_RESET_V1 packet replies with an ACK_V1 message. At this point the renegotiation can start using the CONTROL_V1 OPCODE.¶
When the ACK_V1 packet is being sent, the key_id field MUST be incremented to ensure the connection can still use the old keys for a shorter time until the transition has completed. Any following packets need to use the new key-id until the old key has been removed and the new key-id replaces it completely. [FIXME/schwabe:THIS IS WRONG)¶
[FIXME: Elaborate more on how re-keying happens]¶
Control channel packet, usually TLS protocol data.¶
CONTROL_V1 is used to encapsulate the SSL/TLS protocol into the OpenVPN wire packet, primarily used for the SSL/TLS handshake process. The payload of CONTROL_V1 packets are expected to be processed by an SSL/TLS library. Once the SSL/TLS handshake has completed and the ephemeral session key has been negotiated, encrypted tunnel data will use either DATA_V1 or DATA_V2 for the transport of those packets.¶
Acknowledgment for received control channel packets.¶
When control channel packets have been received an ACK_V1 packet is sent back to confirm its arrival. An ACK_V1 message SHOULD NOT be sent upon receiving an ACK_V1 message.¶
See also Acknowledgments (Section 6.4).¶
Used to start a VPN connection from client, first packet of the three-way handshake.¶
The client starts with a fresh new session key. This tells the server to initiate a new TLS handshake and establish a new session key for data channel going from client to server.¶
Note that the payload of this packet MUST be ignored but might be used to implement early protocol negotiation in the future.¶
Initial packet from server, reply to a CONTROL_HARD_RESET_CLIENT_V2 packet. Second packet in the three-way handshake.¶
In the P2P mode for TLS. Similar to CONTROL_HARD_RESET_CLIENT_V2, but initiated from the server side.¶
Note that the payload of this packet MUST be ignored but might be later used to implement early protocol negotiation in the future.¶
Initial key packet from the client in the three-way handshake from the client when tls-crypt-v2 is in use. See TLS crypt v2 (Section 5.4.3) for more details.¶
Note that the payload of this packet is interpreted by OpenVPN 2.x to be already part of the TLS session. The payload of this packet SHOULD be empty.¶
The tls-crypt packet id of this packet is used to indicate early protocol negotiation. Without early protocol negotiation the first four octets are normally an uint32 in network byte order starting at 0 and increase linearly with later packets. When early protocol negotiation is supported the value is instead 0x0f 00 00 00. The most significant byte of 0x0f indicates that the second highest byte contains flags of supported features (see below). The third byte SHOULD also be 0x00. The fourth byte is expected to be used for retransmission and will linearly increase with retransmissions of the control packet. For packets other than the reset packet, the packet id is just a normal replay counter.¶
Currently no flags are defined for the second byte, yet. But indicating support for early protocol negotiation implies that the client supports sending CONTROL_WKC_V1 (Section 6.2.2.9) packets.¶
Identical to the CONTROL_V1 message but with a wrapped client append to the message similar to the CONTROL_HARD_RESET_CLIENT_V3 message. See TLS crypt v2 (Section 5.4.3) for details.¶
Data channel packet with 4-byte header. This is similar to DATA_V1 with an additional field of 24 bits for Peer-ID.¶
For details about this opcode see the sections AEAD (Section 7.5), and CBC/OFB/CTR (Section 7.6) packet format.¶
The DATA_V1 packet is identical to the DATA_V2 packet apart from op_code being 6 and the peer_id absent from the packet format (all followings fields are shifted by 3 bytes to the left).¶
The DATA_V1 packet are deprecated and should only used for interoperability with old clients.¶
Control channel packets have a message id that orders them and identifies them for ack messages. The message ids are independent for both direction and MUST start at 0. If the message id reaches MAX_UINT32, the implementation MAY implement a rollover to 0 again. However, since such a huge number of control message is unrealistic, an implementation MAY refuse new packets if the message packet id rolls over.¶
OpenVPN has dedicated acknowledgment messages and also allows adding acknowledgments to other control messages. A P_ACK_V1 message usually carries up to 8 acknowledgments while other messages only carry 4 acknowledgments. Unlike other protocols like TCP, OpenVPN does not have cumulative ACKs and each ACK only allows acknowledging a single packet.¶
To avoid retransmissions it is recommended to keep an LRU cache of the most recently seen packets from the peer and always put ACKs for these packets in messages (4 for non P_ACK_V1 and 8 for P_ACK_V1).¶
To ensure compatibility to with the existing OpenVPN implementation the number of ACKs in a single packet (acked_pktid_list) should be limited to 8.¶
The current implementation expects control to be 1250 or smaller. Apart from the early protocol negotiation, all payloads of control packets are TLS data.¶
For the plaintext messages, OpenVPN considers a control message to correspond to a single TLS record. Splitting a plaintext message into two TLS records, will result it to be treated as two separate messages. To send a control message with a larger plaintext, a single TLS record must be split over multiple control messages.¶
Control message should be also separated by a NUL byte. The current implementation might not enforce this behaviour but future implementation that no longer rely on TLS framing might enforce this behaviour. When sending an implementation MUST send each control message in its own TLS record terminated by a NUL byte.¶
struct key_exchange { uint32 null; uint8 method = 2; uint8 key_random[48]; uint8_t random1[32]; uint8_t random2[32]; uint16 occ_string_len; uint8_t* occ_string; uint16 username_len; uint8_t* username; uint16 password_len; uint8_t* password; uint16 peerinfo_len; uint8_t* peerinfo; }¶
All the strings in these packets are expected to be valid UTF8 null-terminated strings. If they are not used (e.g. password and username), they are just a single zero byte. The string length MUST include the trailing null byte.¶
The packets always starts with 4 bytes of zero, followed by one byte of 0x02. After that comes random data that is used with legacy clients to derive the data channel keys (Section 7.1) using a TLS1.0/TLS1.1 style PRF function. These fields are not used in the modern protocol anymore since the data channel key derivation is using TLS export key feature but SHOULD be set to random values.¶
The OCC string is a string that contains a number of parameters that are used to check if client and server are using compatible configuration and warn on mismatches. With more and more dynamic configuration in the OpenVPN protocol, its usefulness is highly diminished.¶
During the handshake, the client will have username and password if username and password authentication is used. Peerinfo (Section 6.7) is also present. The server replies with a key_exchange packet on its own with occ_string, username, password and empty peerinfo.¶
The key_random
, random1
, and random2
only used for older clients that do
not support key derivation via RFC 5705 keying material exporter support. This value should contain
random bytes.¶
The peerinfo is an UTF8 encoded string that contains newline separated (\n
) variables
in the form of VAR=VALUE. The following variables are specified:¶
:
) separated allowed data channel ciphers.¶
Most of the variables are considered optional. Only IV_CIPHERS, IV_PROTO and IV_SSO (if auth pending is supported) MUST be implemented.¶
For IV_PROTO, the bits have the following meaning:¶
If the IV_ACC variable is present, this indicates that the library implements the ACC control message (Section 8.11). The IV_ACC variable indicates the capabilities of the client. IV_ACC has the following format¶
IV_ACC=<maxlen>,<protocol flags>,<custom protocols>¶
maxlen: the maximum length of message this implementation can receive in one message. This is encoded message and depends on the general size of control frame the implementation can handle.¶
The protocol flags are a colon seperated list of flags. Currently defined are:¶
custom protocols is a colon separated list of custom app protocols that are supported. This list should be kept short and the protocol names itself should be short as well as they will repeated with every message that is sent for the protocol.¶
An example would of an IV_ACC message would be for a client that supports base64 and text messages and supports the flower and fortune protocol would be¶
IV_ACC=1400,6:B:m=1400,flower:fortune¶
Negotiation is the process in which two peers agree on the optional features and other negotiable paramters. Some asepects of the protocol cannot be negotiated like tls-crypt or tls-auth as these need to be identical to establish a connection.¶
There are two styles of negotiation in the OpenVPN protocol. Which one is used depends wether PUSH_REQUEST, PUSH_REPLY is used or not.¶
When PUSH_REQUEST is in effect, the server determines the used options and informs the client via PUSH_REPLY and the protocol-flags command about the features to use.¶
In direct peer to peer connection the negotiation is done by each peer determining the common features and ciphers in a determinisic and way. The algorithm is the following:¶
EXPORTER-OpenVPN-p2p-peerid
and a length of 3. Use the resulting three bytes in network byte order as
the peer-id. Otherwise use 0x76706e as peer-id. (ASCII "vpn")¶
OpenVPN uses 256 byte of key material for encryption/decryption of the data channel. The format of this key material is the following:¶
struct datakeys { uint8_t key_c2s[64]; uint8_t auth_c2s[64]; uint8_t key_s2c[64]; uint8_t auth_s2c[64]; }¶
All these keys provide more than enough material to provide encryption keys for all encryption and authentication algorithms. E.g. when 128 bit are required for an encryption cipher, only the first 16 bytes are used. key_c2s and auth_c2s are used to encrypt/authenticate data from client to server and key_s2c and auth_s2c are used to encrypt/authenticate from server to client. Server and client in this context is TLS server and TLS client of the connection.¶
This key structure is normally generated by using RFC 5705 key material exporter [RFC5705]
from the Control Channel session with the label EXPORTER-OpenVPN-datakeys
and using the 256 bytes length of the structure.
Older clients use the mechanism described in the section OpenVPN data channel
PRF.¶
Recent advances in cryptography research have shown that GCM ciphers, most notably AES-GCM have theoretical vulnerabilities when AES-GCM is used with the same key with too many block encryption invocations. See Usage Limits on AEAD Algorithms [usage-limits-aead-draft] and the referenced research papers in that document like [AEAD-LIMITS] for more information.¶
To avoid using the same encryption key for too many packets without requiring to do a full renegotiation OpenVPN uses epoch data channel keys. The term epoch is used to avoid confusion with the already existing term key-id and since DTLS 1.3 [RFC9147] uses the same terminology.¶
A sender should calculate a safe amount of packets to send/number of encryptions that can be done. The actual number depends on the cipher being used. From current standards [usage-limits-aead-draft], there is no limit to consider for Chacha20-Poly1305, so a sender can use the full 48 bit of the epoch counter for encrypting packets before moving to a new epoch and encryption key. Using the calucation outlined in this document with a safety margin of 2^-50 the limit for AES-GCM is 2^32.5 packets with a packet size of 1500 bytes. The TLS 1.3 [RFC8446] standard uses a higher safety margin of 2^-57, which translates to 2^24.5 for maximum TLS record sizes (2^14 or 16kB). OpenVPN implementations should choose the same (higher) safety margin of 2^-57 that also TLS uses.¶
In order to guarantee that safety margin an implementation has to ensure that the number of plain text blocks s and the number of packets q satisfies the following equation:¶
q + s ≤ p^(1/2) * 2^(129/2) - 1¶
Using our confidentially margin of 2^-57, this gives us:¶
q + s ≤ 2^36¶
When an implementation tracks the number of blocks of encrypted clear text and number of cipher invocation data (which is identical to number of sent packets), this formula can be used to determine if the limit has been reached.¶
Alternatively, when not tracking the number of packets, an upper limit per encryption can be set. This limit is called L and is set in number of blocks. E.g. in VPN terms, the maximum packet size divided by the block size, which is 16 bytes. If VPN traffic is very mixed, e.g. a lot of small packets that do not use the full MTU, this will allow less traffic to be encrypted before a rekey is necessary.¶
Implementations that use the simpler approach of only counting the number of packets before switching to a new epoch, must ensure to calculate the limit with the actual maximum size that they are willing to send a packet with and not only with the current MTU size and use L accordingly in the calcualations. E.g. the current OpenVPN implementation will always try to send up to the internal buffer size of 1600 byte in the default configuration.¶
Example calculations for confidentialy limit. This is done do to give an example for an implementation that assumes a fixed L and to give an estimate how many packets can be encrypted assuming assuming a fixed packet size. Using the limits in the documents and p=2^-57 and L=2**10.¶
q ≤ (p^(1/2) * 2^(129/2) - 1) / (L + 1)>¶
gives us basically the same limit that TLS imposes:¶
q ≤ 2^(24.9999)¶
When using L = 2^7 (packet/buffer size of 1500 rounded up to the nearest power of 2 an) we get:¶
q ≤ 2^(26.999)¶
For the integrity limit¶
v ≤ min(2^64, (p * 2^127) / (L + 1))¶
with p=2^-57, and setting v=3^36, we can have L to be up to 2^34 (256 GB). So for packet sizes used in the OpenVPN protocol we ignore this formula as we are always within the safe limits.¶
The following table gives an overview of the limits for number of packets when calculating them with above confidentially formula.¶
packet size | Maximum number of packets |
---|---|
64 | 2^33 |
1500 | 2^29.4 |
1600 | 2^29.3 |
2048 | 2^29 |
4096 | 2^28 |
9000 | 2^26.8 |
16384 | 2^26 |
65336 | 2^24 |
The receiver should count the number of packets that have been received but failed verification. The number of packets that fail verification and we can tolerate is specified differently for DTLS 1.3 and the data usage limit document. For OpenVPN we set the number to the limit of 2^36 packets failed verifications, the same as (D)TLS 1.3, which is lower than the theoretical limit. An implementation may choose a lower number.¶
The epoch key generation is inspired by the TLS key generation and HMAC-based Key Derivation Function (HKDF) [RFC5869] and the definition of HKDF-Expand-Label in TLS 1.3 [RFC8446].¶
OpenVPN uses different epoch keys for the client to server and the server to client direction. The epoch 1 key E_1 are the first 32 bytes of the OpenVPN key's key_c2s and key_s2c respectively. Note, these keys serve the same purpose as the TLS 1.3 client_/server_application_traffic_secret_N keys.¶
We start at epoch 1 instead epoch 0 for the key. This is done to allow for easier implementation for the C-based OpenVPN implementation.¶
For any further key, the key derivation is¶
E_N+1 = OVPN-Expand-Label(E_N, "datakey upd", "", 32)¶
The per epoch data channel key is derived via¶
K_i = OVPN-Expand-Label(E_i, "data_key", "", key_size)¶
implicit_iv = OVPN-Expand-Label(E_i, "data_iv", "", implicit_iv_len)¶
The key K_i will then be used for the actual data encryption. The key_size parameter depends on the key size of the encryption cipher being used. The parameter implicit_iv_len also depends on the IV length of the cipher but for both AES-GCM and Chacha20-Poly1305, this is 12 bytes (96 bits).¶
The function OVPN-Expand-Label is identical to the HKDF-Expand-Label function of TLS 1.3 but uses "ovpn " instead of "tls13 " as the label prefix. The hash function for OVPN-Expand-Label is SHA-256.¶
OVPN-Expand-Label(Secret, Label, Context, Length) = HKDF-Expand(Secret, OvpnLabel, Length) Where OvpnLabel is specified as: struct { uint16 length = Length; opaque label<6..255> = "ovpn " + Label; opaque context<0..255> = Context; } OvpnLabel;¶
Note that like in TLS 1.3 standard the strings here include one byte prefix that specifies the length of of the string.¶
The key size of 4096 bit or 256 byte is used here to make these epoch data channel keys the same format as the regular data channel keys.¶
When sending packets, a peer will encrypt packet until the limit for the epoch K_i is reached. At this point, the sender will switch to the next epoch key K_i+1. The state for the sending side, only needs to keep the current E_i key and the current encryption key K_i.¶
Each peer is expected to hold the current epoch key K_i, the previous K_i-1 and a number of future keys K_i+1, K_i+2,....,K_i+j. The number of future keys j depends on the expected possible data rate of the implementation and needs to be large enough that even when a reasonable amount of packets is lost, the implementation will still be able to authenticate the packets.¶
Allowing multiple epochs keys requires the receiving side to keep multiple keys to able to decrypt and verify packets with different epochs. An attacker can send a packet with a epoch that is a lot higher than the current epoch. In order to avoid needing to the generate/keep arbitrary epoch decryption keys, the window of future decryption keys that is acceptable should be limited. At the same time, the window needs to be large enough that a long packet loss that causes all packets to be dropped (e.g. a topology change) does not cause legitimate packets to be dropped.¶
For example, if we consider an implementation that allows to encrypt at data rate of 100 GBit/s and to be able to deal with 60s of lost data, we have to calculate how many epochs the peer can use and exhaust in this time. Assuming a small packet size of 128 byte, this gives us about 78 million packets per second or about 2^26.2 packets per second. For the full minute we get 2^32.1 packets. Assuming the limit of 2^28.3 packets per epoch for AES-GCM, we need 14 epoch keys to safely encrypt this amount of data. A reasonable amount of future epoch data channel keys in this scenario could be considered 16 or 32 keys.¶
When receiving an authenticated packet with a higher epoch than the currently used one, the receiver of this packet SHOULD also switch to the same epoch. This allow also the receiver to trigger using a new encryption key if in the future it becomes necessary. But this is optional and an implementation can continue using the old send key as log as it is safe.¶
As addition a peer cannot regard apparent overuse of a send key by other the other peer as error as the limit can change if new information is available but the peer MAY move to a higher sending key epoch of its own to try to trigger the same on the peer as outlined in the previous paragraph.¶
This requirement of keeping only one past key but multiple future keys for an implementation is a trade-off. Not being able to decrypt packets from an earlier epoch will result in packet loss while not being to decrypt a legitimate packet from a future epoch, will result in the receiver never switching to the new epoch of the sender and complete loss of the connectivity for that connection. Implementations can opt to also keep multiple previous epoch keys if they don't want to make this trade-off.¶
The purpose of this feature is to allow a client to float between various client IP addresses and UDP ports. When a client floats it means that the established encryption and session keys will be reused when the client's source IP address or source port changes. Reasons for such changes can be NAT firewalls interrupting longer lasting established connections, mobile devices moving from WLAN to a mobile data carrier (such as GPRS, 3G, LTE, etc) and similar scenarios.¶
Each client implementing Peer-ID support MUST indicate its support with the IV_PROTO=2 peerinfo (Section 6.7) variable. By sending IV_PROTO=2 to the server, it means the client will be able to use the DATA_V2 packet format. When the server acknowledges that the client supports IV_PROTO=2/DATA_V2 it SHOULD assign an unique Peer-ID to the client. The server is responsible of keeping track of which Peer-ID is related to which active session and MUST ensure no active clients share the same Peer-ID.¶
Clients MUST accept the peer-id option being passed to it via a PUSH_REPLY message and MUST use this value as the Peer-ID in all DATA_V2 packets. Clients MUST provide a valid Peer-ID in all DATA_V2 packets, but it can be the ID used to indicate Peer-ID being disabled.¶
Server implementations MUST support the IV_PROTO=2 and the DATA_V2 packet format and MUST evaluate the response from the client before assigning and pushing a peer-id option to the client. The server SHOULD use the DATA_V2 packet formats when communicating with the clients.¶
The client is not expected to parse the Peer-ID in DATA_V2 packets. The server should send the same Peer-ID provided in packets from the server to client.¶
The Peer-ID is included protected in the HMAC signature/AEAD tag of DATA_V2 packets.¶
The server MUST ensure the packet integrity is intact, through checking HMAC or GCM authentication tags, replay protection, etc of the DATA_V2 packet.¶
In addition the server MUST ensure the float does not clobber a pre-existing client, such as a client floating to a source IP address used by a different client unless it can be verified that the pre-existing client is a previous instance of the floating client.¶
The replay protection in OpenVPN uses a fairly standard approach with a sliding window with a number of packets n and a timeout t¶
This means that a client needs to keep track of the highest received sequence number and the n sequence ids lower than the highest received sequence number.¶
Old OpenVPN peers before 2.4 will enforce a strict packet ordering when using TCP that does not allow reordering.¶
This specifies the first version of AEAD data format that OpenVPN implements. It has the AEAD tag at the start.¶
struct aead_packet { int opcode:5; int key_id:3; int peer_id:24; uint32_t packet_id; uint8_t[16] authentication_tag; uint8_t* encrypted_payload; }¶
The packet_id together with the implicit IV forms the IV for decryption. The packet_id is also used for the replay protection.¶
IV = packet_id | implicit_iv;¶
The implicit part of IV is filled by first bytes of the auth_c2s/auth_s2c of the data channel key. For the current implemented AEAD ciphers Chacha20-Poly1305 and AES-GCM the IV length is 96 bits, 32 bits are from packet_id and the remaining 64 bits (the implicit IV part) are taken from the data channel key. With 64 bit packet id counters the implicit IV part becomes 32 bit.¶
For DATA_V2 packets the authenticated data includes opcode, key_id and peer_id. For DATA_V1 packets the authenticated data starts on the first byte of packet_id, not including opcode and key_id.¶
authenticated_data_v1 = packet_id | payload authenticated_data_v2 = opcode| key_id | peer_id | packet_id | payload¶
The tag size is always 128 bit (16 bytes). (Same size as in TLS).¶
This is the modern version of the AEAD data format in OpenVPN. The differences to the older format are:¶
The packet format with 64bit counter looks like this:¶
struct aead_packet { int opcode:5; int key_id:3; int peer_id:24; uint_64_t packet_id; uint8_t* encrypted_payload; uint8_t[16] authentication_tag; }¶
The packet id is split into 16 bit bits of epoch and 48-bit of counter for that epoch. Each epoch uses a different a encryption/decryption key and a different implicit_iv. The epoch selects the key to use for decryption.¶
struct packet_id { uint epoch:16; uint epoch_counter:48; }¶
The epoch_counter of the packet_id together with the implicit IV for the epoch forms the IV for decryption. The epoch_counter is also used for the replay protection. Implementations are encouraged to a have a per epoch replay protection. Using the whole packet_id as a flat 64bit counter for replay protection will work as well but will reject reordered packets from the older epochs. A (valid) packet of the new the epoch will be seen as a large gap in the counter that and that will disallow any allow any packet from an earlier epoch.¶
The 96bit IV is constructed by using the 96 bit of implicit IV belonging to the epoch and doing an XOR with the 64 bit packet id of both epoch and epoch_counter.¶
IV = (epoch | epoch_counter) XOR implicit_iv_epoch¶
Note that this IV calculation assumes a big endian representation of the IV. I.e. the 8 bytes on the wire of the epoch counter are XOR with the first 8 bytes of the implicitv_iv_epoch counter and the remaing 4 byte are directly derived from the implict_iv_epoch.¶
This data format is only defined for DATA_V2 packets and therefore the authenticated data includes opcode, key_id and peer_id.¶
authenticated_data = opcode| key_id | peer_id | packet_id | payload¶
The tag size is always 128 bit (16 bytes) appended to the end of encrypted data (Same size as in TLS).¶
struct data_packet_cbc { int opcode:5; int key_id:3; int peer_id:24; uint8_t[HMAC_LEN] hmac; uint8_t[IV_LEN] iv; uint32_t encrypted_packet_id; uint8_t* encrypted_payload }¶
struct data_packet_xfb { int opcode:5; int key_id:3; int peer_id:24; uint8_t[HMAC_LEN] hmac; uint8_t[IV_LEN] iv; uint8_t* encrypted_payload }¶
HMAC_LEN depends on the length of the HMAC being used, e.g. 20 bytes for SHA1, 32 for SHA256. If no authentication is used (DEPRECATED) then the length of the field is 0.¶
The HMAC is computed over the complete remainder of the packet. opcode, key_id, and peer_id are NOT included in the HMAC calculation. If HMAC verification fails decryption of the packet MUST NOT be attempted. OpenVPN implements the encrypt-then-MAC approach.¶
IV_LEN depends on the IV of used cipher. For AES in CBC, CFB and OFB this is 128 bits (IV_LEN=8), for Blowfish in CBC mode (DEPRECATED) 64 bits (IV_LEN=4). For generating the IV use best practices. OpenVPN generates the CBC IV as random bytes with an PRNG. For OFB and CFB the IV has the following format:¶
IV = 64 bit packet ID | IV_remainder¶
The IV_remainder SHOULD be random bytes. OpenVPN 2.x uses all zeros instead.¶
The packet ID in CBC mode is encrypted and included before the payload. In contrast to that, the packet ID in OFB and CFB mode are the first 64 bit of the IV.¶
For unencrypted data packets the same format as CBC without IV is used.¶
This is a deprecated way of deriving the data channel keys. It should be only implemented if compatibility with older OpenVPN versions is required that do not support key derivation via the RFC5705 key material exporter. It also requires the MD5 algorithm which often modern crypto libraries do not readily support anymore.¶
This uses the key_random
, random1
, and random2
from the key
exchange messages. These will be prefixed with client and server here to indicate from which
packet these field are coming. Also the session id of the control channel will be used here¶
Here TLS_PRF(seed, secret) is the TLS PRF function according to RFC 2246 with MD5 and SHA1 as used in TLS 1.0/1.1.¶
seed = "OpenVPN master secret" | client.random1 | server.random1 secret = client.key_random master_secret - TLS_PRF(seed, secret) key_seed = "OpenVPN key expansion " | client.random2 | server.random2 datakeys = TLS_PRF(key_seed, key_seed)¶
After the control channel has been established the format switch from the binary format of the key exchange message to a text based format. The message are sent in plain text. The current implementation does not allow a message to span more than one TLS record.¶
Format:¶
PUSH_REQUEST¶
This message is sent from the client to the server and instructs the server that the
client is ready to receive a PUSH_REPLY
message. The message is periodically repeated
until the PUSH_REPLY
is received for compatibility with old OpenVPN servers and to act as
a keepalive.¶
Format:¶
PUSH_REPLY [comma separated options]¶
This message is sent from the server to the client and has dynamic configuration for the client. See the section "dynamic configuration option" for a detailed description of the options. [FIXME/flichtenheld: proper reference]¶
If the client has set the IV_PROTO_REQUEST_PUSH bit in the IV_PROTO
peerinfo (Section 6.7) client variable the server MAY send a PUSH_REPLY
without waiting for the PUSH_REQUEST
from the client.¶
Format:¶
PUSH_UPDATE [comma separated options]¶
This message includes dynamic configuration options that can be pushed from the server to the client without reconnecting.
These options augment existing options. Options with the same name are replaced. To remove an option, it should be prefixed
with -
. For example, the following code replaces all routes (if there were any) with the provided one and removes the dns
option:¶
PUSH_UPDATE,route 10.10.10.0 255.255.255.0,-dns¶
The client SHOULD support updating all pushed options; otherwise, it SHOULD reconnect. This also applies to removal.¶
Options prefixed with ?
are considered optional. The client MAY support them. If the client cannot support some optional options,
they can be ignored, and the client does not have to reconnect. This also applies to removal. Example syntax:¶
PUSH_UPDATE,-?block-ipv6¶
Here client should remove block-ipv6
option. However, if client does not support updating it, it does not need to reconnect.¶
This message is only sent if the client has set the IV_PROTO_PUSH_UPDATE bit in the IV_PROTO peerinfo (Section 6.7) client variable.¶
Format:¶
AUTH_PENDING¶
or¶
AUTH_PENDING,flags¶
This message is sent from the server to the client to indicate that a multi factor authentication is in use and the authentication is not completed. The authentication can continue inband or out-of-band.¶
flags
is a comma separate key-value list. Currently timeout time
is defined and defines the maximum time the server
expects the client to stay in the pending auth state.¶
The client indicates if the extended format with flags is supported by setting the IV_PROTO_AUTH_PENDING_KW bit in the IV_PROTO peerinfo (Section 6.7) client variable. All new clients MUST support the extended format.¶
Format:¶
RESTART[,message] HALT[,message]¶
and¶
RESTART,[[flags]]message¶
These message are sent from the server to the client and the client to
terminate a session. With HALT
the client is expected to also not try to
try reconnect. With RESTART
the client is expected to reconnect. flags
is
a list of characters that must follow directly after the comma and is
enclosed in [
and ]
. The client SHOULD purge username and password before
reconnecting if flags contains P
and reconnect to the next server unless
N
is in flags in which case it should reconnect to the same server. E.g.
when the client receives a RESTART[PN]
message it should reconnect to same
server with the same username and password.¶
The optional message
indicates a message that can relayed to the user.¶
Format:¶
AUTH_FAILED[,message] AUTH_FAILED,SESSION:message AUTH_FAILED,TEMP[keywords]:message AUTH_FAILED,TEMP:message¶
This message indicates to a client that an authentication attempt was unsuccessful.
This message is mostly send in response to a PULL_REQUEST
or when a client attempts to
renegotiates a TLS session.¶
The optional message can be relayed to the user. If the message starts with SESSION
, this
indicates that current credentials are longer valid. This is mostly used to indicate that
the temporary session credentials that were pushed with "auth-token" and "auth-token-user"
should be purged and the client should reconnect in the same way as a new connection.¶
The AUTH_FAILED,TEMP
message indicates that the authentication temporarily failed and should
the client continue to retry to connect. The server can optionally give a user readable message
and hint the client a behavior how to proceed. The keywords of AUTH_FAILED,TEMP
are comma separated
keys/values. Currently defined are:¶
backoff s
- instructs the client to wait at least s seconds before the next connection attempt. If
the client has already a higher delay before reconnecting, the delay should NOT be shortened.¶
advance addr
- Instructs the client to reconnect to the (IP) address of the current server.¶
advance remote
- Instructs the client to skip the remaining IP addresses of the current server and instead
connect to the next server specified in the configuration file¶
advance no
- Instructs the client to retry connecting to the same server again.¶
For example a server that might send AUTH_FAILED,TEMP[backoff 42,advance no]: No free IP addresses
to indicate
that the VPN connection can currently not succeed and instructs the client to retry in 42 seconds again.¶
The client will announce the capability of understanding AUTH_FAILED,TEMP
message by setting the
IV_PROTO_AUTH_FAILED_TEMP bit in the IV_PROTO peerinfo (Section 6.7) client variable. A client that does not understand the AUTH_FAILED,TEMP
message
will treat this recoverable error as a non-recoverable error.¶
Format:¶
EXIT¶
This message indicates that the peer has terminated and the connection can be torn down.¶
Format:¶
CR_RESPONSE,base64reply¶
This message indicates a reply to prior challenge/response request. The response is specific to the challenge response and is encoded with base64.¶
Format:¶
INFO_PRE,EXTRA INFO,EXTRA¶
This message is used to send pending auth parameters. See the section on pending auth for more details
on the format of the EXTRA
parameter. [FIXME/flichtenheld: proper reference]¶
Format:¶
ACC,<proto>,<encoding>,<len>,<payload>¶
This message is the same in both directions.¶
The dns option is used to configure the DNS server the client should use. The option is follow by a space seperated list of feature flags.¶
The¶
protocol-flags¶
directive tells a client what OpenVPN protocol features to use.¶
cc-exit¶
explicit exit notifies should be sent via the control channel instead of using an OCC message.¶
tls-ekm¶
The OpenVPN key (Section 7.1) for the data channel enryption should be derived using TLS key material exporter¶
dyn-tls-crypt¶
Renegotion control channel use dynamic TLS crypt¶
aead-epoch¶
Epoch keys and the Section 7.5 data format are used¶
TBD¶
TBD¶
TBD¶
TBD¶
TBD¶
The HMAC packet authentication (Section 5.3) and Control packet encryption (Section 5.4) use pre-shared keys. The pre-shared key format is based on the internal OpenVPN key (Section 7.1) data structure.¶
The file contains header line "-----BEGIN OpenVPN Static key V1-----", followed by each of the 256 bytes of the structure encodes as hexacdecimal ascii. After 16 bytes (32 characters in the output), a new line is started. Finally, an footer line "-----END OpenVPN Static key V1-----" ends the encoding of the block.¶
# 2048 bit encoded as a key -----BEGIN OpenVPN Static key V1----- 112233445566778899a0b0ccd0efa1a2 [ 14 lines skipped ] 998877aaffe1838139aabbff88a2a3a6 -----END OpenVPN Static key V1-----¶
Anything outside the header line and footer line MUST be ignored when parsing a static key file. Implementations SHOULD be able to handle different number of bytes per line when parsing the file.¶