mirror of https://github.com/dswd/vpncloud.git
491 lines
21 KiB
Plaintext
491 lines
21 KiB
Plaintext
vpncloud(1)
|
|
===========
|
|
|
|
== Name
|
|
vpncloud - Peer-to-peer VPN
|
|
|
|
|
|
== SYNOPSIS
|
|
|
|
*vpncloud [options] [--config <file>] [-p <password>] [-l <addr>] [-c <addr>...]*
|
|
|
|
|
|
== OPTIONS
|
|
|
|
*--config <file>*::
|
|
Read configuration options from the specified file. Please see the section
|
|
*CONFIG FILES* for documentation on the file format.
|
|
If the same option is defined in the config file and as a parameter, the
|
|
parameter overrides the config file.
|
|
|
|
*-t <type>*, *--type <type>*::
|
|
Set the type of network. There are two options: *tap* devices process
|
|
Ethernet frames *tun* devices process IP packets. [default: *tun*]
|
|
|
|
*-d <name>*, *--device <name>*::
|
|
Name of the virtual device. Any *%d* will be filled with a free number.
|
|
[default: *vpncloud%d*]
|
|
|
|
*--device-path <path>*::
|
|
The path of the base device inode, e.g. /dev/net/tun.
|
|
|
|
*--fix-rp-filter*::
|
|
If this option is set, VpnCloud will change the rp_filter settings to protect
|
|
against a potential system vulnerability. See *SECURITY* for more info.
|
|
|
|
*-m <mode>*, *--mode <mode>*::
|
|
The mode of the VPN. The VPN can like a router, a switch or a hub. A *hub*
|
|
will send all data always to all peers. A *switch* will learn addresses
|
|
from incoming data and only send data to all peers when the address is
|
|
unknown. A *router* will send data according to known subnets of the
|
|
peers and ignore them otherwise. The *normal* mode is switch for tap
|
|
devices and router for tun devices. [default: *normal*]
|
|
|
|
*-l <addr>*, *--listen <addr>*::
|
|
The address on which to listen for data. This can be simply a port number
|
|
or a full address in form IP:PORT. If the IP is specified as \'\*' or only
|
|
a port number is given, then the socket will listen on all IPs (v4 and v6),
|
|
otherwise the socket will only listen on the given IP. [default: **3210**]
|
|
|
|
*-c <addr>*, *--peer <addr>*, *--connect <addr>*::
|
|
Address of a peer to connect to. The address should be in the form
|
|
*addr:port*. If the node is not started, the connection will be retried
|
|
periodically. This parameter can be repeated to connect to multiple peers.
|
|
|
|
*--claim <subnet>*::
|
|
The local subnets to claim. This parameter should be in the form
|
|
*address/prefixlen* where address is an IPv4 address, an IPv6 address, or a
|
|
MAC address. The prefix length is the number of significant front bits that
|
|
distinguish the subnet from other subnets. Example: *10.1.1.0/24*.
|
|
|
|
*--no-auto-claim*::
|
|
Do not automatically claim the IP set on the virtual interface (on TUN
|
|
devices).
|
|
|
|
*-p <key>*, *--password <key>*::
|
|
A password to encrypt the VPN data. This parameter must be set unless a
|
|
password is given in a config file or a private key is set.
|
|
See *SECURITY* for more info.
|
|
|
|
*--key <key>*, *--private-key <key>*::
|
|
A private key to use for encryption. The key must be given as base62 as
|
|
generated by *--genkey*. See *SECURITY* for more info.
|
|
|
|
*--public-key <key>*::
|
|
A public key matching the given private key. The key must be given as base62
|
|
as generated by *--genkey*. This argument is purely optional. See *SECURITY*
|
|
for more info.
|
|
|
|
*--trust <key>*, **--trusted-key <key>*::
|
|
A public key to trust. Any peer must have a key pair that is trusted by this
|
|
node, otherwise it will be rejected. The key must be given as base62 as
|
|
generated by *--genkey*. This argument can be given multiple times. If it is
|
|
not set, only the own public key will be trusted. See *SECURITY* for more
|
|
info.
|
|
|
|
*--genkey*::
|
|
Generate and print a random key pair and exit. The key pair is printed as
|
|
base62 and can be used as private-key, public-key and trusted-key options.
|
|
|
|
*--algo <method>*, *--algorithm <method>*::
|
|
Supported encryption algorithms ("plain", "aes128", "aes256", or "chacha20").
|
|
Nodes exchange the supported algorithms and select the one that is fastest on
|
|
both ends. This parameter can be given multiple times to enable multiple
|
|
algorithms. *Warning:* "plain" means unencrypted and needs to be enabled
|
|
explicitly. As default, all algorithms except "plain" are enabled.
|
|
|
|
*--peer-timeout <secs>*::
|
|
Peer timeout in seconds. The peers will exchange information periodically
|
|
and drop peers that are silent for this period of time. [default: *300*]
|
|
|
|
*--keepalive <secs>*::
|
|
Interval of peer exchange messages in seconds. The peers will exchange
|
|
information periodically to keep connections alive. This setting overrides
|
|
how often this will happen. [default: *peer-timeout/2-60*]
|
|
|
|
*--switch-timeout <secs>*::
|
|
Switch table entry timeout in seconds. This parameter is only used in switch
|
|
mode. Addresses that have not been seen for the given period of time will
|
|
be forgotten. [default: *300*]
|
|
|
|
*--beacon-store <path|command>*::
|
|
Periodically store beacons containing the address of this node in the given
|
|
file or via the given command. If the parameter value starts with a pipe
|
|
character (*|*), the rest of the value is interpreted as a shell command.
|
|
Otherwise the value is interpreted as a file to write the beacon to.
|
|
If this parameter is not given, beacon storage is disabled.
|
|
Please see the section *BEACONS* for more information.
|
|
|
|
*--beacon-load <path|command>*::
|
|
Periodically load beacons containing the addresses of other nodes from the
|
|
given file or via the given command. If the parameter value starts with a
|
|
pipe character (*|*), the rest of the value is interpreted as a shell
|
|
command. Otherwise the value is interpreted as a file to read the beacon
|
|
from.
|
|
If this parameter is not given, beacon loading is disabled.
|
|
Please see the section *BEACONS* for more information.
|
|
|
|
*--beacon-interval <secs>*::
|
|
Beacon storage/loading interval in seconds. If configured to do so via
|
|
*--beacon-store* and *--beacon-load*, the node will periodically store its
|
|
beacon and load beacons of other nodes. This parameter defines the interval
|
|
in seconds. [default: *3600*]
|
|
|
|
*--beacon-password <password>*::
|
|
An optional password to use to encrypt all beacon data. See the section
|
|
*BEACONS* for more information.
|
|
|
|
*--ip <address>*::
|
|
An IP address (plus optional prefix length) for the interface. If this
|
|
argument is given, the address (and if a prefix length is given, also the
|
|
netmask) is configured on the device and the device is activated.
|
|
If also *--ifup* is given, the interface is configured before the ifup
|
|
command is executed. Please see *DEVICE SETUP* for more info.
|
|
|
|
*--ifup <command>*::
|
|
A command to setup the network interface. The command will be run (as
|
|
parameter to *sh -c*) when the device has been created to configure it.
|
|
The name of the allocated device will be available via the environment
|
|
variable *IFNAME*.
|
|
Please note that this command is executed with the full permissions of the
|
|
caller. Please see *DEVICE SETUP* for more info.
|
|
|
|
*--ifdown <command>*::
|
|
A command to bring down the network interface. The command will be run (as
|
|
parameter to *sh -c*) to remove any configuration from the device.
|
|
The name of the allocated device will be available via the environment
|
|
variable *IFNAME*.
|
|
Please note that this command is executed with the (limited) permissions of
|
|
the user and group given as *--user* and *--group*.
|
|
|
|
*--pid-file <file>*::
|
|
Store the process id in this file when running in the background. If set,
|
|
the given file will be created containing the process id of the new
|
|
background process. This option is only used when running in background.
|
|
|
|
*--user <user>*::
|
|
*--group <group>*::
|
|
Change the user and/or group of the process once all the setup has been
|
|
done.
|
|
|
|
*--log-file <file>*::
|
|
If set, print logs also to the given file. The file will be created and
|
|
truncated if is exists.
|
|
|
|
*--stats-file <file>*::
|
|
If set, periodically write statistics on peers and current traffic to the
|
|
given file. The file will be periodically overwritten with new data.
|
|
|
|
*--statsd-server <server>*::
|
|
If set, periodically send statistics on current traffic and some important
|
|
events to the given statsd server (host:port).
|
|
|
|
*--statsd-prefix <prefix>*::
|
|
Sets the prefix to use for all statsd entries. [default: **vpncloud**]
|
|
|
|
*--daemon*::
|
|
Spawn a background process instead of running the process in the foreground.
|
|
If this flag is set, the process will first carry out all the
|
|
initialization, then drop permissions if *--user* or *--group* is used and
|
|
then spawn a background process and write its process id to a file if
|
|
*--pid-file* is set. Then, the main process will exit and the background
|
|
process continues to provide the VPN. At the time, when the main process
|
|
exits, the interface exists and is properly configured to be used.
|
|
|
|
*--no-port-forwarding*::
|
|
Disable automatic port forward. If this option is not set, VpnCloud tries to
|
|
detect a NAT router and automatically add a port forwarding to it.
|
|
|
|
*-v*, *--verbose*::
|
|
Print debug information, including information for data being received and
|
|
sent.
|
|
|
|
*-q*, *--quiet*::
|
|
Only print errors and warnings.
|
|
|
|
*-h*, *--help*::
|
|
Display the help.
|
|
|
|
|
|
== DESCRIPTION
|
|
|
|
*VpnCloud* is a peer-to-peer VPN over UDP. It creates a virtual network
|
|
interface on the host and forwards all received data via UDP to the
|
|
destination. It can work in 3 different modes:
|
|
|
|
*Switch mode*:: In this mode, the VPN will dynamically learn addresses
|
|
as they are used as source addresses by peers and use them to forward data to
|
|
its destination. Addresses that have not been seen for some time
|
|
(option *switch_timeout*) will be forgotten. Data for unknown addresses will be
|
|
broadcast to all peers. This mode is the default mode for TAP devices that
|
|
process Ethernet frames but it can also be used with TUN devices and IP
|
|
packets.
|
|
*Hub mode*:: In this mode, all data will always be broadcast to all peers.
|
|
This mode uses lots of bandwidth and should only be used in special cases.
|
|
*Router mode*:: In this mode, data will be forwarded based on preconfigured
|
|
address ranges ("claims"). Data for unclaimed addresses will be silently
|
|
ignored. This mode is the default mode for TUN devices that work with IP
|
|
packets but it can also be used with TAP devices and Ethernet frames.
|
|
|
|
All connected VpnCloud nodes will form a peer-to-peer network and cross-connect
|
|
automatically until the network is fully connected. The nodes will periodically
|
|
exchange information with the other nodes to signal that they are still active
|
|
and to allow the automatic cross-connect behavior. There are some important
|
|
things to note:
|
|
|
|
. The cross-connect behavior can be able to connect nodes that are behind
|
|
firewalls or NATs as it can function as hole-punching.
|
|
. The management traffic will increase with the peer number quadratically.
|
|
It should still be reasonably small for high node numbers (below 10 KiB/s
|
|
for 10.000 nodes). A longer *peer_timeout* can be used to reduce the traffic
|
|
further. For high node numbers, router mode should be used as it never
|
|
broadcasts data.
|
|
|
|
VpnCloud does not implement any loop-avoidance. Since data received on the UDP
|
|
socket will only be sent to the local network interface and vice versa, VpnCloud
|
|
cannot produce loops on its own. On a TAP device, however STP data can be
|
|
transported to avoid loops caused by other network components.
|
|
|
|
For TAP devices, IEEE 802.1q frames (VLAN tagged) are detected and forwarded
|
|
based on separate MAC tables. Any nested tags (Q-in-Q) will be ignored.
|
|
|
|
|
|
== EXAMPLES
|
|
|
|
=== Simple multi-node connectivity
|
|
|
|
In the example scenario, a simple layer-3 network tunnel is established. Most
|
|
likely those commands need to be run as *root* using *sudo*.
|
|
|
|
First, VpnCloud need to be started on both nodes (the address after *-c* is the
|
|
address of the remote node and the the *X* in the interface address must be
|
|
unique among all nodes, e.g. 0, 1, 2, ...):
|
|
|
|
----
|
|
vpncloud -c REMOTE_HOST:PORT --ip 10.0.0.X/24 --password PASSWORD
|
|
----
|
|
|
|
Afterwards, the interface can be used to communicate.
|
|
|
|
=== Routed TUN example
|
|
|
|
In this example, 2 nodes and their subnets should communicate using IP.
|
|
First, VpnCloud need to be started on both nodes:
|
|
|
|
----
|
|
vpncloud -t tun -c REMOTE_HOST:PORT --ip 10.0.X.1 --claim 10.0.X.0/24 --password PASSWORD
|
|
----
|
|
|
|
It is important to configure the interface in a way that all addresses on the
|
|
VPN can be reached directly. E.g. if subnets 10.0.1.0/24, 10.0.2.0/24 and so on
|
|
are used, the interface needs to be configured as 10.0.1.1/16.
|
|
For TUN devices, this means that the prefix length of the subnets
|
|
(/24 in this example) must be different than the prefix length that the
|
|
interface is configured with (/16 in this example).
|
|
|
|
=== Important notes
|
|
|
|
. VpnCloud can be used to connect two separate networks. TAP networks can be
|
|
bridged using *brctl* and TUN networks must be routed. It is very important
|
|
to be careful when setting up such a scenario in order to avoid network loops,
|
|
security issues, DHCP issues and many more problems.
|
|
. TAP devices will forward DHCP data. If done intentionally, this can be used
|
|
to assign unique addresses to all participants. If this happens accidentally,
|
|
it can conflict with DHCP servers of the local network and can have severe
|
|
side effects.
|
|
|
|
|
|
== CONFIG FILES
|
|
|
|
The config file is a YAML file that contains configuration values. All entries
|
|
are optional and override the defaults. Please see the section *OPTIONS* for
|
|
detailed descriptions of the options.
|
|
|
|
*device*:: A key-value map with device settings
|
|
*type*:: Set the type of network. Same as *--type*
|
|
*name*:: Name of the virtual device. Same as *--device*
|
|
*path*:: Set the path of the base device. Same as *--device-path*
|
|
*fix-rp-filter*:: Fix the rp_filter settings on the host. Same as *--fix-rp-filter*
|
|
*ip*:: An IP address (plus optional prefix length) for the interface. Same as *--ip*
|
|
*ifup*:: A command to setup the network interface. Same as *--ifup*
|
|
*ifdown*:: A command to bring down the network interface. Same as *--ifdown*
|
|
*crypto*:: A key-value map with crypto settings
|
|
*algorithms*:: The encryption algorithms to support. See *--algorithm*
|
|
*password*:: The password to use for encryption. Same as *--password*
|
|
*private-key*:: The private key to use. Same as *--private-key*
|
|
*public-key*:: The public key to use. Same as *--public-key*
|
|
*trusted-keys*:: Other public keys to trust. See *--trusted-key*
|
|
*listen*:: The address on which to listen for data. Same as *--listen*
|
|
*peers*:: A list of addresses to connect to. See *--connect*
|
|
*peer_timeout*:: Peer timeout in seconds. Same as *--peer-timeout*
|
|
*keepalive*:: Periodically send message to keep connections alive. Same as *--keepalive*
|
|
*beacon*:: A key-value map with beacon settings
|
|
*store*:: Path or command to store beacons. Same as *--beacon-store*
|
|
*load*:: Path or command to load beacons. Same as *--beacon-load*
|
|
*interval*:: Interval for loading and storing beacons in seconds. Same as *--beacon-interval*
|
|
*password*:: Password to encrypt the beacon with. Same as *--beacon-password*
|
|
*mode*:: The mode of the VPN. Same as *--mode*
|
|
*switch_timeout*:: Switch table entry timeout in seconds. Same as *--switch-timeout*
|
|
*claims*:: A list of local subnets to claim. See *--claim*
|
|
*auto-claim*:: Whether to automatically claim the device ip. See *--no-auto-claim*
|
|
*port_forwarding*:: Whether to activate port forwardig. See *--no-port-forwarding*
|
|
*user*:: The name of a user to run the background process under. Same as *--user*
|
|
*group*:: The name of a group to run the background process under. Same as *--group*
|
|
*pid_file*:: The path of the pid file to create. Same as *--pid-file*
|
|
*stats_file*:: The path of the statistics file. Same as *--stats-file*
|
|
*statsd*:: A key-value map with statsd settings
|
|
*server*:: Server to report statistics to. Same as *--statsd-server*
|
|
*prefix*:: Prefix to use when reporting to statsd. Same as *--statsd-prefix*
|
|
|
|
=== Example
|
|
|
|
device:
|
|
type: tun
|
|
name: vpncloud%d
|
|
ip: 10.0.1.1/16
|
|
crypto:
|
|
password: mysecret
|
|
listen: 3210
|
|
peers:
|
|
- remote.machine.foo:3210
|
|
- remote.machine.bar:3210
|
|
peer_timeout: 600
|
|
mode: normal
|
|
claims:
|
|
- 10.0.1.0/24
|
|
port_forwarding: true
|
|
user: nobody
|
|
group: nogroup
|
|
pid_file: /run/vpncloud.pid
|
|
|
|
|
|
== SECURITY
|
|
|
|
VpnCloud uses strong cryptography based on modern cryptographic primitives.
|
|
|
|
Before exchanging any payload data with peers a secure connection is
|
|
initialized based on key pairs. Each node has a key pair consisting of a
|
|
private and a public key (*--private-key* and *--public-key*). Those key pairs
|
|
can be generated via *--genkey*.
|
|
To allow connections, nodes need to list the public keys of all other nodes as
|
|
trusted keys (*--trusted-key*). To simplify the key exchange, key pairs can be
|
|
derived from passwords (*--password*). If no trusted keys are configured, nodes
|
|
will only trust their own public key. Nodes configured with the same password
|
|
will therefore trust each others.
|
|
|
|
In the initialization phase of the connection, nodes agree on a temporary key
|
|
that is used to encrypt the next messages using a fast encryption algorithm.
|
|
VpnCloud automatically benchmarks all supported algorithms and negotiates to
|
|
use the fastest algorithm for each connection. Users can limit the supported
|
|
algorithms if they wish using *--algorithm*. Although highly discouraged, users
|
|
can opt out of encryption altogether by enabling the *plain* algorithm. (Note:
|
|
both nodes in a connection must support this, otherwise encryption will take
|
|
place.)
|
|
|
|
The temporary encryption keys are rotated periodically so they are never used
|
|
for a longer time.
|
|
|
|
Please refer to the security whitepaper for more details.
|
|
|
|
=== CVE-2019-14899
|
|
|
|
The Linux kernel contains a vulnerability that affects all VPNs disregarding of
|
|
the specific technology being used. Under some circumstances, the kernel accepts
|
|
packets for the address range configured on the vpn interface also on other
|
|
interfaces. This way, an attacker can test the presence of a VPN and find out
|
|
the IPs being used. Also the attacker can with some effort inject data and
|
|
manipulate connections that should be protected by the VPN.
|
|
To mitigate this, the rp_filter setting should be configured to strict mode,
|
|
which unfortunately a lot of distributions do not set as default.
|
|
VpnCloud will detect this misconfiguration and offers to fix it via
|
|
*--fix-rp-filter*.
|
|
Note: This vulnerability affects all VPN technologies as it is not located in
|
|
the VPN software but in the Linux kernel.
|
|
|
|
|
|
== BEACONS
|
|
|
|
Beacons are short character sequences that contain a timestamp and a list of
|
|
addresses. They can be published and retrieved by other nodes to find peers
|
|
without the need for static addresses.
|
|
|
|
The beacons are short (less than 100 characters), encrypted and encoded with
|
|
printable characters to allow publishing them in various places on the
|
|
internet, e.g.:
|
|
|
|
* On shared drives or synchronized folders (e.g. on Dropbox)
|
|
* Via a dedicated database
|
|
* Via a general purpose message board of message service (e.g. Twitter)
|
|
|
|
The beacons are very robust. They only consist of alphanumeric characters
|
|
and can be interleaved with non-alphanumeric characters (e.g. whitespace).
|
|
Also the beacons contain a prefix and suffix that depends on the configured
|
|
network magic and secret key (if set) so that all nodes can find beacons in
|
|
a long text.
|
|
|
|
When beacons are stored or loaded via a command (using the pipe character *|*),
|
|
the command is interpreted using the configured shell *sh*. This command has
|
|
access to the following environment variables:
|
|
|
|
*$begin*:: The prefix of the beacon.
|
|
*$end*:: The suffix of the beacon.
|
|
*$data* (only on store):: The middle part of the beacon. Do not use this
|
|
without prefix and suffix!
|
|
*$beacon* (only on store):: The full beacon consisting of prefix, data and
|
|
suffix.
|
|
The commands are called in separate threads, so even longer running commands
|
|
will not block the node.
|
|
|
|
|
|
== STATSD SUPPORT
|
|
|
|
When a statsd server is configured (either via **--statsd-server** or the
|
|
config option **statsd_server**), VpnCloud sends out the following statistics
|
|
every minute.
|
|
|
|
Gauge values:
|
|
*peer_count*:: Current number of peers
|
|
*table_entries*:: Number of routing table / switch table entries
|
|
|
|
The following statistics consist of two keys: *.bytes* and *.packets* that hold
|
|
the values in bytes and packets. All values refer to the traffic during the
|
|
last minute:
|
|
*traffic.protocol.inbound*:: Complete incoming traffic with all peers
|
|
*traffic.protocol.outbound*:: Complete outgoing traffic with all peers
|
|
*traffic.payload.inbound*:: Incoming payload traffic with all peers
|
|
*traffic.payload.outbound*:: Outgoing payload traffic with all peers
|
|
*invalid_protocol_traffic*:: Invalid incoming protocol traffic
|
|
*dropped_payload*:: Outgoing traffic that could not be routed
|
|
|
|
All keys are prefixed by a common prefix. The prefix defaults to *vpncloud* but
|
|
can be changed via **--statsd-prefix** or the config option **statsd_prefix**.
|
|
|
|
|
|
== DEVICE SETUP
|
|
|
|
The device is setup using the following steps:
|
|
|
|
. The device is created with the type and name given as *--type* and *--device*.
|
|
. Depending on the device type and the main network device of the systme, the
|
|
optimal MTU is determined and configured on the device.
|
|
. If and IP address (and optional prefix length) is given via *--ip*, the
|
|
interface is configured with the address and the given netmask (default:
|
|
255.255.255.0). Also the interface is set to be active.
|
|
. If a command is given as *--ifup*, the given command will be executed. The
|
|
name of the interface is stored in an environment variable as "IFNAME". Note
|
|
that VpnCloud waits for the command to exit before starting its normal
|
|
operation.
|
|
|
|
Note that most of the steps will need elevated permissions, so the vpncloud
|
|
command needs to be executed as root (e.g. via sudo). Beware that the ifup
|
|
command will also be executed using those permissions.
|
|
|
|
VpnCloud can drop the elevated permissions when *--user* and *--group* is
|
|
given.
|
|
|
|
|
|
== COPYRIGHT
|
|
|
|
Copyright (C) 2015-2020 Dennis Schwerdel
|
|
This software is licensed under GPL-3 or newer (see LICENSE.md)
|