Prepare release

This commit is contained in:
Dennis Schwerdel 2021-02-05 18:27:48 +01:00
parent ed260d9a98
commit 13688edd75
6 changed files with 174 additions and 42 deletions

View File

@ -11,6 +11,7 @@ This project follows [semantic versioning](http://semver.org).
- [changed] Updated dependencies
- [changed] Changed Rust version to 1.49.0
- [fixed] Added missing peer address propagation
- [fixed] Fixed problem with peer addresses without port
### v2.0.1 (2020-11-07)

8
Cargo.lock generated
View File

@ -376,9 +376,9 @@ checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691"
[[package]]
name = "idna"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
checksum = "de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094"
dependencies = [
"matches",
"unicode-bidi",
@ -911,9 +911,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "standback"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66a8cff4fa24853fdf6b51f75c6d7f8206d7c75cab4e467bcd7f25c2b1febe0"
checksum = "a2beb4d1860a61f571530b3f855a1b538d0200f7871c63331ecd6f17b1f014f8"
dependencies = [
"version_check",
]

View File

@ -242,12 +242,8 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
///
/// This method adds a peer to the list of nodes to reconnect to. A periodic task will try to
/// connect to the peer if it is not already connected.
pub fn add_reconnect_peer(&mut self, mut add: String) {
pub fn add_reconnect_peer(&mut self, add: String) {
let now = TS::now();
if add.find(':').unwrap_or(0) <= add.find(']').unwrap_or(0) {
// : not present or only in IPv6 address
add = format!("{}:{}", add, DEFAULT_PORT)
}
let resolved = match resolve(&add as &str) {
Ok(addrs) => addrs,
Err(err) => {
@ -465,7 +461,6 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
self.next_stats_out = now + STATS_INTERVAL;
self.traffic.period(Some(5));
}
// TODO: every 5 minutes: EVENT periodic
if let Some(peers) = self.beacon_serializer.get_cmd_results() {
debug!("Loaded beacon with peers: {:?}", peers);
for peer in peers {

View File

@ -497,7 +497,11 @@ pub struct Args {
pub enum Command {
/// Generate and print a key-pair and exit
#[structopt(name = "genkey", alias = "gen-key")]
GenKey,
GenKey {
/// The shared password to encrypt all traffic
#[structopt(short, long, env)]
password: Option<String>,
},
/// Run a websocket proxy
#[cfg(feature = "websocket")]
@ -519,7 +523,7 @@ pub enum Command {
/// Generate shell completions
Completion {
/// Shell to create completions for
#[structopt(long)]
#[structopt(long, default_value="bash")]
shell: Shell
}
}

View File

@ -45,7 +45,7 @@ use std::{
use crate::{
cloud::GenericCloud,
config::{Args, Command, Config},
config::{Args, Command, Config, DEFAULT_PORT},
crypto::Crypto,
device::{Device, TunTapDevice, Type},
net::Socket,
@ -185,7 +185,11 @@ fn run<P: Protocol, S: Socket>(config: Config, socket: S) {
};
let mut cloud =
GenericCloud::<TunTapDevice, P, S, SystemTimeSource>::new(&config, socket, device, port_forwarding, stats_file);
for addr in config.peers {
for mut addr in config.peers {
if addr.find(':').unwrap_or(0) <= addr.find(']').unwrap_or(0) {
// : not present or only in IPv6 address
addr = format!("{}:{}", addr, DEFAULT_PORT)
}
try_fail!(cloud.connect(&addr as &str), "Failed to send message to {}: {}", &addr);
cloud.add_reconnect_peer(addr);
}
@ -239,8 +243,8 @@ fn main() {
});
if let Some(cmd) = args.cmd {
match cmd {
Command::GenKey => {
let (privkey, pubkey) = Crypto::generate_keypair(args.password.as_deref());
Command::GenKey { password } => {
let (privkey, pubkey) = Crypto::generate_keypair(password.as_deref());
println!("Private key: {}\nPublic key: {}\n", privkey, pubkey);
println!(
"Attention: Keep the private key secret and use only the public key on other nodes to establish trust."

View File

@ -45,7 +45,10 @@ vpncloud - Peer-to-peer VPN
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**]
otherwise the socket will only listen on the given IP.
Alternatively, a websocket proxy URL (starting with ws://) can be given
here. Please see the section *WEBSOCKET PROXY* for more info.
[default: **3210**]
*-c <addr>*, *--peer <addr>*, *--connect <addr>*::
Address of a peer to connect to. The address should be in the form
@ -62,31 +65,27 @@ vpncloud - Peer-to-peer VPN
Do not automatically claim the IP set on the virtual interface (on TUN
devices).
*-p <key>*, *--password <key>*::
*-p <password>*, *--password <password>*::
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.
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*
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
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
@ -179,9 +178,11 @@ vpncloud - Peer-to-peer VPN
*--statsd-server <server>*::
If set, periodically send statistics on current traffic and some important
events to the given statsd server (host:port).
Please see *STATSD SUPPORT* for more info.
*--statsd-prefix <prefix>*::
Sets the prefix to use for all statsd entries. [default: **vpncloud**]
Please see *STATSD SUPPORT* for more info.
*--daemon*::
Spawn a background process instead of running the process in the foreground.
@ -196,6 +197,12 @@ vpncloud - Peer-to-peer VPN
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.
*--hook <script>*::
Call the given script on an event. If the script is in the format *event:script*,
it will only be called for the specified event type, otherwise it will be called
for all events. This parameter can be given multiple times.
Please see the section *HOOK SCRIPTS* for more info.
*-v*, *--verbose*::
Print debug information, including information for data being received and
sent.
@ -207,6 +214,41 @@ vpncloud - Peer-to-peer VPN
Display the help.
== SUBCOMMANDS
The following subcommands can be given to run some special action instead of
running a VpnCloud instance. Any parameters must be given after the subcommand
name (except for -v -q and -h). Only the listed parameters are accepted for the
subcommands.
*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.
See *SECURITY* for more info.
*-p <password>*, *--password <password>*:::
Derive the key pair from the given password instead of creating randomly.
*ws-proxy*::
Run a websocket proxy instead of the normal VpnCloud instance.
See *WEBSOCKET PROXY* for more info.
*-l <addr>*, *--listen <addr>*:::
Listen on the given TCP address (IP:PORT or PORT). [default: **3210**]
*migrate-config*::
Migrate an old config to the current config format.
*--config-file*:::
The path of the config file to convert.
*completion*::
Output shell completions for the VpnCloud command.
*--shell*:::
The shell type to create completions for. [default: **bash**]
== DESCRIPTION
*VpnCloud* is a peer-to-peer VPN over UDP. It creates a virtual network
@ -302,28 +344,28 @@ 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*
*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*
*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*
*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*
@ -334,8 +376,10 @@ detailed descriptions of the options.
*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*
*server*::: Server to report statistics to. Same as *--statsd-server*
*prefix*::: Prefix to use when reporting to statsd. Same as *--statsd-prefix*
*hook*:: A hook script to be called for every event type. See *HOOK SCRIPTS* for info.
*hooks*:: A map of event type to script for scripts that only fire for one event type. See *HOOK SCRIPTS* for info.
=== Example
@ -366,7 +410,7 @@ 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*.
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
@ -461,6 +505,90 @@ 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**.
== WEBSOCKET PROXY
The websocket proxy mode replaces the local UDP port by a websocket proxy to allow
connectivity even in very restricted environments.
This means that instead of listening on a local port for incoming messages and
sending outgoing messages via this port, all UDP traffic will be forwarded to and
received from a remote proxy via the websocket protocol. This proxy opens a UDP
port for each VpnCloud instance that connects to it. The instance can use this port
remotely just like it would use a real local UDP port.
The proxy is transparent, it does not manipulate or even decrypt the messages it
forwards. Trust relations are still created between VpnCloud instances, not between
an instance and the proxy. The proxy only ever sees encrypted messages. Therefore,
the connection to it uses plain HTTP.
A websocket proxy can be stared by using the *ws-proxy* subcommand. A custom port
can be set using the *--listen* parameter. (Note that this port never conflicts
with a VpnCloud port on the same machine since VpnCloud uses UDP and the proxy uses
TCP.)
A VpnCloud instance can use a websocket proxy instead of opening a local port by
specifying the websocket proxy via its *--listen* parameter
(e.g. *--listen ws://example.com:3210*). Note that the websocket URL must start with
*ws:\/\/*, not *http:\/\/*.
== HOOK SCRIPTS
VpnCloud supports calling hook scripts on certain events. The scripts can either be
configured on the command line or in the config file. Hook scripts can either be
configured per event type or globally.
When an event occurs, the specified hook script is executed using
the current permissions of the user that started the instance. Note that this means
that if VpnCloud is configured to drop permissions, only the events *device_setup*
and *device_configured* will be executed using root permissions.
Hook scripts are executed using *sh -c*, so either binaries, shell scripts and even
shell commands can be used. The script will be executed in parallel to the VpnCloud
instance. Its output will be printed to the stdout of VpnCloud and the return code
is ignored.
The hook script will receive information on the event using environment variables.
The variable *EVENT* will contain the name of the event. Other variables depend on
the event type.
The following event types
*peer_connecting*::
A new peer connection is in the process of being established. The variable
*PEER* contains the address of the peer but no other information is known at
that point in time.
Variables: *IFNAME*, *PEER*
*peer_connected*::
A new peer successfully connected to this instance. Besides the peer address,
also a list of claims (*CLAIMS*, space separated) and the node id of the new
peer (*NODE_ID*) are given to the script.
Variables: *IFNAME*, *PEER*, *CLAIMS*, *NODE_ID*
*peer_disconnected*::
A peer connection has been closed. If the peer has been fully connected, the
node id is given (*NODE_ID*).
Variables: *IFNAME*, *PEER*, (*NODE_ID*)
*device_setup*::
This event is fired when the virtual device has been created but not yet
configured.
Variables: *IFNAME*
*device_configured*::
This event is fired when the virtual device is fully configured.
Variables: *IFNAME*
*vpn_started*::
This event is fired when the VPN is ready to be used.
Variables: *IFNAME*
*vpn_shutdown*::
This event is fired when the VPN s shutting down.
Variables: *IFNAME*
== DEVICE SETUP
The device is setup using the following steps: