Crates.io | tokio-sando |
lib.rs | tokio-sando |
version | 0.1.0 |
source | src |
created_at | 2021-04-11 17:53:54.306207 |
updated_at | 2021-04-11 17:53:54.306207 |
description | A simple proxy server implementation |
homepage | |
repository | https://github.com/ChunMinChang/tokio-sando |
max_upload_size | |
id | 382108 |
size | 52,913 |
This is a simple proxy server implementation based on tokio.
The proxy is a server sandwiched (sando in Japanese) between the client and the client's destination. It will ask for the data from the destination on behalf of its client. In another word, the proxy essentially acts as a VPN. Please see how it works to know more.
Open two terminals. One for the server, one for the client.
127.0.0.1 proxy.tokio.sando
in your /etc/hosts
proxy.tokio.sando
is the host name registered in the domain.crt
./server
../client
.
./client
is based on curl
. Make sure its version is higher than 7.68.0
. Otherwise, we cannot send HTTP requests in parallel.You can set the pattern for the destination's URL, in regex expression. For example, you can run the following commands:
On server side:
cargo run -- 127.0.0.1:7878 --pkcs12 domain.p12 --password "^G#=QVbVhh7Bt8t9L" --destination-pattern "([a-z]).(mozilla|rust-lang).org"
On client side:
# Work
curl -vp --proxy "https://proxy.tokio.sando:7878" --proxy-cacert domain.crt "https://www.rust-lang.org/"
# Work
curl -vp --proxy "https://proxy.tokio.sando:7878" --proxy-cacert domain.crt "https://www.mozilla.org/en-US/"
# Won't work. Doesn't match "([a-z]).(mozilla|rust-lang).org" pattern
curl -vp --proxy "https://proxy.tokio.sando:7878" --proxy-cacert domain.crt "https://en.wikipedia.org/"
This repo has a built-in certificate. If the certificate is expired or you wish to generate your own certificate, run the commands below:
Generate a Self-Signed Certificate
openssl req \
-newkey rsa:2048 -nodes -keyout domain.key \
-x509 -days 365 -out domain.crt
proxy.tokio.sando
in client.sh
with the Common Name
registered in the domain.crt
domain.crt
, please update it in client.sh
as wellPack the certificate and the private key into a PKCS12 file
openssl pkcs12 \
-inkey domain.key \
-in domain.crt \
-export -out domain.p12
^G#=QVbVhh7Bt8t9L
in the server.sh
by your new passworddomain.p12
, please update it in server.sh
as wellNow the server.sh
and client.sh
should work with your own certificate
Here is a server-client example.
client proxy destination
| | |
* <--- 1 ---> * |
| | |
* ---- 2 ---> * ---- 3 ---> *
| | |
* <--- 5 ---- * <--- 4 ---- *
| | |
* ----------> * ----------> * relay data: client -> destination
| | |
* <---------- * <---------- * relay data: destination -> client
| | |
One use case for the proxy is the privacy-preserving service. Once the proxy builds the tunnel, the client can talk to the destination anonymously if the data relay via the tunnel is in HTTPS. The destination knows the client's request, but it has no idea of who the client is. The proxy knows both who the client and the destination are, but it has no idea of what they are talking about.
A demo here is the giphy search. Open two terminals. One for the server, one for the client.
Add 127.0.0.1 proxy.tokio.sando
in your /etc/hosts
if 127.0.0.1 proxy.tokio.sando
is not there yet
On server-side, run ./server
, or the following command if the server is for giphy service only
cargo run -- 127.0.0.1:7878 \
--pkcs12 domain.p12 \ # or your own PKCS12 file
--password "^G#=QVbVhh7Bt8t9L" \ # or your new password if using your own PKCS12 file
--destination-pattern "api.giphy.com" # Server only accept HTTP CONNECT to "api.giphy.com"
On client side, run ./giphy_search.sh
to search the gif anonymously.
Please ensure the HTTP CONNECT request, which asks to relay data between the client and the destination, is in HTTPS protocol. Otherwise, the proxy will know the contents transferred between the client and the destination if tunnel communication is in HTTP since HTTP transfers data in plain text.
std::io::Error
is thrown. The proxy should send the response to client indicating the error encountered, instead of dropping the connection silently. Once the TLS between client and proxy is established, the proxy should be able to send message back to client400 Bad Request
or else to client if the client request is incomplete or invalid
full
feature from tokio