Crates.io | shadowrocks |
lib.rs | shadowrocks |
version | 0.1.0 |
source | src |
created_at | 2020-05-27 05:32:53.403701 |
updated_at | 2020-05-27 05:32:53.403701 |
description | Shadowsocks port in pure async/.await Rust. |
homepage | https://github.com/ditsing/shadowrocks-async |
repository | https://github.com/ditsing/shadowrocks-async |
max_upload_size | |
id | 246550 |
size | 244,129 |
Throwing rocks against the wall
Shadowrocks is a shadowsocks
port written in pure async/.await
Rust.
At the moment it only does the basics: tunneling from a local SOCKS5 server to a remote server, with
proper encryption. The implementation is thoroughly tested and is compatible with the original
python version with --compatible-mode
.
The official Rust implementation of shadowsocks
can be found here. It has way more
functionality.
To start the local SOCKS5 server at port 51980
, run
cargo run -- -l 51980 -s 127.0.0.1 -p 51986 -k test-password
In the meantime, start the remote shadow server by running
cargo run -- --shadow -s 127.0.0.1 -p 51986 -k test-password
The server address (-s
), server port (-p
) and password (-k
) flags must match.
JSON configuration files (-c
) are also supported. ss://
URLs described
in SIP002 will come soon.
Five types of ciphers are supported:
chacha20-ietf-poly1305
provided by sodiumxchacha20-ietf-poly1305
provided by sodiumaes-128-gcm
by OpenSSLaes-192-gcm
by OpenSSLaes-256-gcm
by OpenSSLAll of them are AEAD ciphers.
In non-compatible mode, a few changes are made to the traffic between the socks server and shadow server.
PBKDF2
, as opposite to PBKDF1
used in
the original version. Master key is still derived from the password.HKDF
with SHA256
, instead of SHA1
, which is
no longer considered secure. The input key to HKDF
is still the master key.Item #3 helps defend against replay attacks. If we can reasonably assume that salt generated is different each time, then both servers have to re-encrypt traffic for every new connection. Attackers will need to derive a different sub-key for the replied session, which cannot be done without the master key.
In compatible mode, shadowrocks
behaves the same as the original version.
src/crypto
in detailss://
URL and JSON config fileBoth the ring
crate (BoringSSL) and the openssl
crate are used.
The functionality largely overlaps between those two. ring
was originally
used as a reference point and sanity check to openssl
, when the author is
unfamiliar with the crypto used in shadowsocks
.
ring
and openssl
feature tablefeatures | ring |
openssl |
---|---|---|
PBKDF1 |
✅ | |
PBKDF2 |
✅ | ✅ |
HKDF-SHA1 |
✅ | ✅ |
HKDF-SHA256 |
✅ | ✅ |
AES-128-GCM |
✅ | ✅ |
AES-192-GCM |
✅ | |
AES-256-GCM |
✅ | ✅ |
HKDF-SHA1
support was recently added to ring
.
The ring
crate can be disabled by disabling feature ring-crypto
. The
openssl
crate cannot be completely disabled at the moment.
The current implementation does a lot of small memory allocations for each connection. For example, to send the SOCKS 5 address from socks server to remote shadow server, the following process is followed.
x
bytes, x = 2
).x
bytes, x = 2
).x
varies.To summarize, 13 allocations for each packet. Each encryption costs 6 allocations, and each packet we have to encrypt twice: once for packet length and once for the actual information.
The process for reading is similar.
We saved one step for the "ciphertext without tag" part. Nonetheless this is still terrible.