Logo Peer-to-peer VPN

Security of VpnCloud

This page will explain the security concepts of VpnCloud. This should serve two purposes:

TL;DR: VpnCloud should be pretty secure if you

Programming Language

Before diving into how the code is written, let's first take a look into what language it is written in. VpnCloud is written in the Rust programming language, which has been invented by Mozilla to be both efficient and secure - properties, that I wanted for VpnCloud. While Rust programs achieve similar performance to programs written in C or C++, the language is fundamentally more secure. Rust has strong guarantees for memory safety. As long as there is no bug in the compiler, programs written in Rust should be free from most memory-related security problems that are well known from C and C++.

Since the safety guarantees of Rust come with some restrictions, sometimes one needs to circumvent those restrictions. Rust has a built-in mechanism to do so: "unsafe" code. Rust allows developers to write code that Rust can not guarantee to be safe and mark that code as unsafe. Whenever this code is called, the caller must make sure that the usage is actually safe and wrap the call in an unsafe block. This mechanism allows developers to combine automatic safety guarantees of the language with manually-checked code.

Since version 1.5 VpnCloud is 100% Rust code. That means that all of VpnCloud is guarded by the strong safety guarantees of the Rust language.

"Unsafe" code in VpnCloud

VpnCloud contains a few instances of the "unsafe" keyword to

Those calls have been reviewed multiple times by me and I consider them safe.

Encryption

VpnCloud uses the library ring to provide encryption. Ring is written in Rust but also contains lots of hand-written assembler code for performance reasons. The library provides low-level cryptographic methods that are used in VpnCloud to encrypt protocol and payload data.

In the initialization of a connection, both peers perform a handshake. The messages of the handshake are authenticated so that the receiver can verify the integrity of the message and detect any manipulation or forgery. During the handshake, both peers negotiate an encryption method and common key material. Also they exchange initial peer information for the VpnCloud protocol.

The connection initialization can only be performed by a peer using a key that is listed in the trusted keys of the receiver. Any forgery or tempering is automatically detected and the initialization is aborted. Also all sensitive information in the handshake is already encrypted.

VpnCloud supports 3 different encryption methods: ChaCha20 combined with Poly1305 (see RFC7539) and AES128 and AES256 in GCM mode. All 3 methods are very efficient (with AES128 and AES256 even being accelerated by modern CPUs) and widely considered secure. The usage of the methods to encrypt and decrypt messages is the same regardless of the method used.

The encryption always affects the whole message (including the VPN payload, if any), except a small header containing a message number. All supported encryption algorithms take a 96 bit nonce, that is initialized with a random value and incremented each time when encrypting a message. The nonce is added to the message in front of the encrypted data and sent along in the message. The encryption algorithms calculate a 128 bit tag, that is automatically appended to the message and protects it from alteration.

The encryption works in a single message mode. Each message is encrypted and decrypted on its own without relation to previous messages. Any scheme that relates message encryption to earlier messages would be more complex as messages could be lost, duplicated or reordered during transmission. However, VpnCloud contains a protection against replay attacks, that automatically detects and rejects old packets.

The encryption is based on key material that is negotiated on each connection and rotated frequently. The keys that are used are ephemeral (i.e. short-lived, never transmitted nor stored anywhere), in order to provide perfect forward secrecy.

The peer authentication is based on elliptic curve key pairs based on Curve25519. Users can either specify the key pair explicitly or have it derived from a passphrase. When deriving the key from a passphrase, VpnCloud uses PBKDF2_HMAC_SHA256 with 4096 iterations and a salt unique to VpnCloud. The key pair is never transmitted over the network.

Plain encryption

VpnCloud also supports disabling encryption as an explicit opt-out. If two peers both allow unencrypted connections, their connection will be unencrypted. That means, that they still carry out a handshake with full authentication but then downgrade to an unencrypted connection for the rest of the communication.

In this case all payload as well as any protocol messages can be read and even manipulated by the network. Please note that this also includes information about all other connections of a node (even if those connections are encrypted).

Please only enable this setting if you are aware of all the consequences and are in control of the network between the two nodes.

Port Forwarding and NAT Routers

Most NAT routers allow nodes inside the NAT to request ports on the public IP address to be redirected to a port on an internal IP address (the ports do not have to be the same). Otherwise most NAT routers only assign ephemeral ports during address translation and only keep them open for a certain IP (or IP range) for limited time in order to receive a reply.

In order for VpnCloud to connect nodes behind NAT routers reliably, it supports establishing port forwardings using the IGD Protocol. A VpnCloud instance will first detect a NAT router and then request the forwarding of a port to its address. After receiving the port forwarding grant, the instance will periodically extend the grant to keep the port open. This default behavior can be disabled using the --no-port-forwarding switch.

Since the IGD protocol is relatively complex and requires supporting the HTTP protocol it opens up a bigger attack surface. Although also the library used for the IGD protocol is written in Rust and therefore less likely to have critical bugs, users that do not trust their network router, should disable this feature.

In general, nodes inside the NAT can not be reached directly by nodes on the Internet. By using a VPN, this restriction can be overcome, so that specific nodes can reach the nodes inside the NAT. Users should be aware that the NAT provides a layer of security that the VPN circumvents. Using the VPN, specific nodes inside the NAT can now be reached by specific nodes from the Internet, which opens them up to attacks from those nodes.

Attack Scenarios

The following scenarios explain the security concepts and attack vectors in different situations with the attacker having different knowledge and capabilities matching some common scenarios.

Scenario 1: Ordinary attacks from the internet

Attacker capabilities & knowledge: The attacker can send packets to at least one peer of a VPN

In order to establish a new connection with any node of the VPN, the attacker would have to perform a connection initialization with any of the nodes. Since this initialization is protected by the elliptic key pairs, this requires either breaking the elliptic encryption algorithm or guessing the private key of one peer, both of which is practically impossible.

The attacker could also try to inject data into an existing connection by manipulating the source address. If the connection is encrypted, the attacker must either break the used encryption algorithm, guess the current ephemeral key or guess the correct authentication tag, all of which is practically impossible.

If the VPN is unencrypted, the attacker can inject data into the connection:

Scenario 2: Attack by the network

Attacker capabilities & knowledge:

The attacker can manipulate the whole network traffic, i.e.

Being able to suppress packets of peers, the attacker is able to remove peers from the VPN by suppressing all of their packets. Also the attacker can execute a denial of service by dropping all or some selected packets of the VPN. The attacker can also split the network into two or more networks by dropping all packets between the peers of different split networks.

If the VPN is encrypted, the attacker is not able to read the communication within the network without breaking the encryption or guessing the encryption key. Also the attacker can not send or manipulate data within the VPN as the encryption contains tags that prevent forging or manipulation of messages. Since the encryption is based on single messages, the attacker can suppress, delay, and duplicate messages within a short period of time (i.e. 1-2 seconds). The VpnCloud protocol is resistant to those attacks, as those are effects that also happen in the Internet by chance.

The attacker can not take a message sent by one peer and instead send it using the address of a different peer. This is prevented by the per-connection encryption.

If connections in the VPN are not encrypted, the attacker can read all the payload data and see the inner communication of those connections. It can also manipulate the payload, or forge payload packets and send them using any source address.

Scenario 3: Attack by a peer

Attacker capabilities & knowledge: The attacker is part of the VPN as a peer. This includes knowledge of one trusted private key and the current encryption key (if any) of at least one connection.

The attacker will learn the addresses of all other peers (by the peer list exchange) and the addresses used within the VPN (either by IP claims of the peers or by listening to the ARP protocol). This information can be used for further attacks on peers and their provided services.

Being a peer, the attacker can send VpnCloud protocol messages to other nodes. In this case, the attack surface is the whole packet forwarding and message parsing code in VpnCloud. However, this code has been written with security in mind in a language that is built to provide safety guarantees. Thus, the likelihood of there being a bug that allows the attacker to send specially crafted VpnCloud messages to execute arbitrary code on the peer is very very low. Nevertheless, VpnCloud supports parameters to drop privileges after setting up the interface and to run as a unprivileged user from there on. The service definition of VpnCloud restricts the service even further, e.g. disallowing most filesystem accesses.

Using the VpnCloud protocol, the attacker can claim any address within the VPN and if necessary steal that address from another peer. The attacker can redirect selected traffic within the VPN to itself.

The attacker can send forged packets within the VPN with any source IP address. This is not restricted to addresses within in VPN network. Under default settings, Linux filters out any packets received on a networking interface with a source address that would not be routed via that interface. This behavior is called "reverse path filtering" and can be disabled by the "rp_filter" option of the interface. If this setting is disabled at a node, packets with forged source addresses ("martian packets") can be sent by the attacker. Please see CVE-2019-14899 for a common misconfiguration that affects this setting.

The attacker can send packets to peers with any destination IP address. Under default settings, Linux will not forward packets with destination addresses that do not belong to the node. This behavior can be changed by the "ip_forward" option of a network interface. If enabled, the node will forward packets with any destination address to that address via routing. The attacker can use this to reach and attack addresses via the peer that it could not reach directly. In most cases however, the attacker will not be able to receive replies from the destination as that would require additional routing settings at the destination.

Some of those attacks could be prevented by applying iptables rules to the virtual interfaces that restrict communication based on IP address ranges. Also VpnCloud nodes should only change the default interface options if necessary.

Security History

Since the start of the project in 2015, VpnCloud had only one security related issue. The problematic code was pushed to the codebase but removed 2 days later before the next release, so no release version was affected. Nevertheless a security announcement was issued and measures were taken to avoid similar bugs in the future.

No other security related issues have been reported or observed.