Wireguard POC
This commit is contained in:
Generated
+128
-11
@@ -542,6 +542,29 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boringtun"
|
||||
version = "0.5.2"
|
||||
source = "git+https://github.com/durch/boringtun.git#a65d78339157dcedca1dd97de23a4b111f4da0b1"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"base64 0.13.1",
|
||||
"blake2 0.10.6",
|
||||
"chacha20poly1305",
|
||||
"hex",
|
||||
"hmac 0.12.1",
|
||||
"ip_network",
|
||||
"ip_network_table",
|
||||
"libc",
|
||||
"nix",
|
||||
"parking_lot 0.12.1",
|
||||
"rand_core 0.6.4",
|
||||
"ring",
|
||||
"tracing",
|
||||
"untrusted 0.9.0",
|
||||
"x25519-dalek 2.0.0-rc.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.4.0"
|
||||
@@ -1308,6 +1331,33 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.0.0-rc.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436ace70fc06e06f7f689d2624dc4e2f0ea666efb5aa704215f7249ae6e047a7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"fiat-crypto",
|
||||
"platforms",
|
||||
"rustc_version 0.4.0",
|
||||
"subtle 2.4.1",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek-derive"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cw-controllers"
|
||||
version = "0.13.4"
|
||||
@@ -1603,7 +1653,7 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"curve25519-dalek 3.2.0",
|
||||
"ed25519",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
@@ -1618,7 +1668,7 @@ version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"curve25519-dalek 3.2.0",
|
||||
"hashbrown 0.12.3",
|
||||
"hex",
|
||||
"rand_core 0.6.4",
|
||||
@@ -1832,6 +1882,12 @@ dependencies = [
|
||||
"subtle 2.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fiat-crypto"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77"
|
||||
|
||||
[[package]]
|
||||
name = "figment"
|
||||
version = "0.10.8"
|
||||
@@ -2763,6 +2819,28 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ip_network"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1"
|
||||
|
||||
[[package]]
|
||||
name = "ip_network_table"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4099b7cfc5c5e2fe8c5edf3f6f7adf7a714c9cc697534f63a5a5da30397cb2c0"
|
||||
dependencies = [
|
||||
"ip_network",
|
||||
"ip_network_table-deps-treebitmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ip_network_table-deps-treebitmap"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d"
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.7.2"
|
||||
@@ -3226,6 +3304,18 @@ dependencies = [
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no-std-compat"
|
||||
version = "0.4.1"
|
||||
@@ -3762,7 +3852,7 @@ dependencies = [
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
"thiserror",
|
||||
"x25519-dalek",
|
||||
"x25519-dalek 1.1.1",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -3804,7 +3894,9 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"atty",
|
||||
"base64 0.21.2",
|
||||
"bip39",
|
||||
"boringtun",
|
||||
"bs58",
|
||||
"clap 4.2.7",
|
||||
"colored",
|
||||
@@ -3844,6 +3936,7 @@ dependencies = [
|
||||
"tokio-tungstenite 0.14.0",
|
||||
"tokio-util",
|
||||
"url",
|
||||
"x25519-dalek 2.0.0-rc.3",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -4184,7 +4277,7 @@ dependencies = [
|
||||
"chacha20",
|
||||
"chacha20poly1305",
|
||||
"criterion",
|
||||
"curve25519-dalek",
|
||||
"curve25519-dalek 3.2.0",
|
||||
"fastrand",
|
||||
"getrandom 0.2.10",
|
||||
"log",
|
||||
@@ -5164,6 +5257,12 @@ version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "platforms"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.4"
|
||||
@@ -5795,7 +5894,7 @@ dependencies = [
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin 0.5.2",
|
||||
"untrusted",
|
||||
"untrusted 0.7.1",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
@@ -6119,7 +6218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
"untrusted 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6129,7 +6228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
"untrusted 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6500,7 +6599,7 @@ dependencies = [
|
||||
"bs58",
|
||||
"byteorder",
|
||||
"chacha",
|
||||
"curve25519-dalek",
|
||||
"curve25519-dalek 3.2.0",
|
||||
"digest 0.9.0",
|
||||
"hkdf 0.11.0",
|
||||
"hmac 0.11.0",
|
||||
@@ -7691,6 +7790,12 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "unwind_safe"
|
||||
version = "0.1.0"
|
||||
@@ -7937,7 +8042,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
"untrusted 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7947,7 +8052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
"untrusted 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8208,12 +8313,24 @@ version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"curve25519-dalek 3.2.0",
|
||||
"rand_core 0.5.1",
|
||||
"serde",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x25519-dalek"
|
||||
version = "2.0.0-rc.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7fae07da688e17059d5886712c933bb0520f15eff2e09cfa18e30968f4e63a"
|
||||
dependencies = [
|
||||
"curve25519-dalek 4.0.0-rc.3",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "0.5.1"
|
||||
|
||||
+24
-3
@@ -34,16 +34,35 @@ pretty_env_logger = "0.4"
|
||||
rand = "0.7"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
sqlx = { version = "0.5", features = [ "runtime-tokio-rustls", "sqlite", "macros", "migrate", ] }
|
||||
sqlx = { version = "0.5", features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
subtle-encoding = { version = "0.5", features = ["bech32-preview"] }
|
||||
thiserror = "1"
|
||||
tokio = { version = "1.24.1", features = [ "rt-multi-thread", "net", "signal", "fs", ] }
|
||||
tokio = { version = "1.24.1", features = [
|
||||
"rt-multi-thread",
|
||||
"net",
|
||||
"signal",
|
||||
"fs",
|
||||
] }
|
||||
tokio-stream = { version = "0.1.11", features = ["fs"] }
|
||||
tokio-tungstenite = "0.14"
|
||||
tokio-util = { version = "0.7.4", features = ["codec"] }
|
||||
url = { version = "2.2", features = ["serde"] }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
# wireguard
|
||||
# Forked it to be able to bump x25519-dalek to rc.3
|
||||
boringtun = { git = "https://github.com/durch/boringtun.git" }
|
||||
base64 = "0.21"
|
||||
x25519-dalek = { version = "=2.0.0-rc.3", features = [
|
||||
"reusable_secrets",
|
||||
"static_secrets",
|
||||
] }
|
||||
|
||||
# internal
|
||||
nym-api-requests = { path = "../nym-api/nym-api-requests" }
|
||||
nym-bin-common = { path = "../common/bin-common", features = ["output_format"] }
|
||||
@@ -60,7 +79,9 @@ nym-sphinx = { path = "../common/nymsphinx" }
|
||||
nym-statistics-common = { path = "../common/statistics" }
|
||||
nym-task = { path = "../common/task" }
|
||||
nym-types = { path = "../common/types" }
|
||||
nym-validator-client = { path = "../common/client-libs/validator-client", features = [ "nyxd-client" ] }
|
||||
nym-validator-client = { path = "../common/client-libs/validator-client", features = [
|
||||
"nyxd-client",
|
||||
] }
|
||||
|
||||
[build-dependencies]
|
||||
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::node::client_handling::websocket::connection_handler::coconut::Coconu
|
||||
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
|
||||
use crate::node::statistics::collector::GatewayStatisticsCollector;
|
||||
use crate::node::storage::Storage;
|
||||
use crate::node::wireguard::wireguard;
|
||||
use log::*;
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_crypto::asymmetric::{encryption, identity};
|
||||
@@ -28,6 +29,7 @@ pub(crate) mod client_handling;
|
||||
pub(crate) mod mixnet_handling;
|
||||
pub(crate) mod statistics;
|
||||
pub(crate) mod storage;
|
||||
pub (crate) mod wireguard;
|
||||
|
||||
/// Wire up and create Gateway instance
|
||||
pub(crate) async fn create_gateway(config: Config) -> Gateway<PersistentStorage> {
|
||||
@@ -297,6 +299,8 @@ impl<St> Gateway<St> {
|
||||
Arc::new(coconut_verifier),
|
||||
);
|
||||
|
||||
tokio::spawn(wireguard());
|
||||
|
||||
info!("Finished nym gateway startup procedure - it should now be able to receive mix and client traffic!");
|
||||
|
||||
self.wait_for_interrupt(shutdown).await
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use base64::engine::general_purpose;
|
||||
use base64::Engine as _;
|
||||
use boringtun::noise::{rate_limiter::RateLimiter, Tunn, TunnResult};
|
||||
use log::{debug, error, info};
|
||||
use tokio::net::UdpSocket;
|
||||
use x25519_dalek::{PublicKey, StaticSecret};
|
||||
|
||||
pub async fn wireguard() {
|
||||
let wg_address = "127.0.0.1:51820";
|
||||
let sock = UdpSocket::bind(wg_address).await.unwrap();
|
||||
info!("wg listening on {wg_address}");
|
||||
|
||||
// Secret key ofthe gateway, we'll need a way to generate this from the IdentityKey, might be enough to do some base58 -> base64 conversion
|
||||
let secret_bytes: [u8; 32] = general_purpose::STANDARD
|
||||
.decode("MBbPChSpmC/FXwIWNROltjd6cOywC81GNEgH9jMOOFk=")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
// Hardcoded peer public key, we'll need a way to register those, private key for that one is `aMUcuAgTiFCHQ/fHqEQRvpLWBxh8sKA7f7lSyWymrGE=`
|
||||
// Wireguard configuration that works with this setup is below, this needs to be put into the wireguard client of choice.
|
||||
// Working in this case means that they go through the handshake, and client
|
||||
// starts sending data packets to the gateway.
|
||||
//
|
||||
// [Interface]
|
||||
// PrivateKey = aMUcuAgTiFCHQ/fHqEQRvpLWBxh8sKA7f7lSyWymrGE=
|
||||
// Address = 10.8.0.0/24
|
||||
// DNS = 1.1.1.1
|
||||
//
|
||||
// [Peer]
|
||||
// PublicKey = y6/iGYraJjON6pw9fcBa5vLRbGsQqprFLfWKyJQnlWs=
|
||||
// AllowedIPs = 0.0.0.0/0
|
||||
// Endpoint = 127.0.0.1:51820
|
||||
let peer_public_bytes: [u8; 32] = general_purpose::STANDARD
|
||||
.decode("JpJzoO1DY6HZbn2h33GQJg0GLnxfdpOeV9C/rvdZ5Cs=")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let peer_public = PublicKey::from(peer_public_bytes);
|
||||
let secret = StaticSecret::try_from(secret_bytes).unwrap();
|
||||
let public = PublicKey::from(&secret);
|
||||
info!(
|
||||
"wg public key: {}",
|
||||
general_purpose::STANDARD.encode(public)
|
||||
);
|
||||
// Rate limiter is global for the gateway
|
||||
let rate_limiter = Arc::new(RateLimiter::new(&public, 1024));
|
||||
|
||||
let mut tun = Tunn::new(secret, peer_public, None, None, 0, Some(rate_limiter)).unwrap();
|
||||
// Here we have a pretty suboptimal implementation of the UDP communication, for one client
|
||||
loop {
|
||||
let mut buf = [0; 1024];
|
||||
let mut dst = vec![0; 1024];
|
||||
let (len, addr) = sock.recv_from(&mut buf).await.unwrap();
|
||||
let packet = Tunn::parse_incoming_packet(&buf[..len]).unwrap();
|
||||
debug!("packet: {:?}", packet);
|
||||
let dst_addr = Tunn::dst_address(&buf[..len]);
|
||||
debug!("dst_addr: {:?}", dst_addr);
|
||||
let result = tun.decapsulate(dst_addr, &buf[..len], &mut dst);
|
||||
loop {
|
||||
debug!("result: {:?}", result);
|
||||
match result {
|
||||
TunnResult::Done => break,
|
||||
// We'll get here during the handshake process, if the reponse is WriteToNetwork we should call decapsulate again with an
|
||||
// empty datagram until we get a Done response
|
||||
TunnResult::WriteToNetwork(p) => {
|
||||
let len = sock.send_to(p, addr).await.unwrap();
|
||||
debug!("{} bytes sent to {}", len, addr);
|
||||
tun.decapsulate(dst_addr, &[], p);
|
||||
break;
|
||||
}
|
||||
TunnResult::Err(e) => {
|
||||
error!("error: {:?}", e);
|
||||
break;
|
||||
}
|
||||
// We've recieved some DataPackets we need to forward and send response back to the initiating client
|
||||
// if no data packets are available we should send an empty packet as an ack.
|
||||
// For now this just logs that it received the packet, and send and ack back to the client.
|
||||
TunnResult::WriteToTunnelV4(ref _r, _addy) => {
|
||||
// These are very spammy
|
||||
debug!("WriteToTunnelV4");
|
||||
sock.send_to(&empty_packet(&mut tun), addr).await.unwrap();
|
||||
}
|
||||
TunnResult::WriteToTunnelV6(ref _r, _addy) => {
|
||||
// These are very spammy
|
||||
debug!("WriteToTunnelV6");
|
||||
sock.send_to(&empty_packet(&mut tun), addr).await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn empty_packet(tun: &mut Tunn) -> [u8; 128] {
|
||||
let mut dst = [0; 128];
|
||||
tun.encapsulate(&[], &mut dst);
|
||||
dst
|
||||
}
|
||||
Reference in New Issue
Block a user