diff --git a/Cargo.lock b/Cargo.lock index 8aa17d9..ffb9ccd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1179,7 +1179,7 @@ dependencies = [ [[package]] name = "omnip" -version = "0.5.1" +version = "0.6.0" dependencies = [ "android_logger", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 55db16b..1188b30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnip" -version = "0.5.1" +version = "0.6.0" edition = "2021" [lib] diff --git a/README.md b/README.md index 9e0ca88..4ea30c7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -omnip - {tcp / http proxy / socks proxy} over quic +omnip - [tcp | udp | http proxy | socks proxy] over quic -------- -An all in one proxy implementation written in Rust. +An all-in-one proxy written in Rust. Features -------- @@ -16,18 +16,24 @@ Features * `omnip -a socks5://127.0.0.1:9000 --upstream http+quic://DOMAIN:3515 -lD` Note: The commands above will use auto-generated self-signed certificate for QUIC, which is for demonstration only. Domain name with certificate issued by trusted CA is recommended. For more details, see README of the [rstun](https://github.com/neevek/rstun) project, which omnip uses to implement proxy over QUIC. And remember to set a password for the server with the `-p` or `--password` option. 5. Supports plain tcp connections over QUIC, which can be used to expose a port of remote server through the QUIC tunnel, for example: - * Start a QUIC server that forwards all its payload to the local SSH port: - * `omnip -a tcp+quic://0.0.0.0:3515 -upstream tcp://127.0.0.1:22 -lD` + * Start a QUIC server that forwards all its tcp payload to the local SSH port: + * `omnip -a tcp+quic://0.0.0.0:3515 --upstream tcp://127.0.0.1:22 -lD` * Connect to the tunnel server and SSH into the remote server through the QUIC tunnel: - * `omnip -a tcp://0.0.0.0:3721 -upstream tcp+quic://DOMAIN:3515 -lD` + * `omnip -a tcp://0.0.0.0:3721 --upstream tcp+quic://DOMAIN:3515 -lD` * `ssh -p 3721 user@127.0.0.1` -6. Supports simple proxy rules, traffic will be relayed to upstream if the requested domain matches one of the proxy rules, this is for achieving *Smart Proxy* to control which domains should be forwarded through the tunnel, for example: +6. Supports plain udp tunneling over QUIC, for example: + * Start a QUIC server that forwards all its udp payload to `1.1.1.1:53`: + * `omnip -a udp+quic://0.0.0.0:3515 --upstream udp://1.1.1.1:53 -lD` + * Connect to the tunnel server and resolve DNS via the tunnel: + * `omnip -a udp://0.0.0.0:5353 --upstream udp+quic://DOMAIN:3515 -lD` + * `dig @127.0.0.1 -p 5353 github.com` +7. Supports simple proxy rules, traffic will be relayed to upstream if the requested domain matches one of the proxy rules, this is for achieving *Smart Proxy* to control which domains should be forwarded through the tunnel, for example: * example.com * .example.com * ||example.com * ... -7. Supports DoT (DNS-over-TLS) or custom name servers, for example: `--dot-server dns.google`, `--name-servers 1.1.1.1,8.8.8.8`, if both are specified, DoT server takes precedence. -8. Simple Web UI can be accessed from the same port of the proxy server, DNS servers and tunnel connection can be configured through the Web UI. +8. Supports DoT (DNS-over-TLS) or custom name servers, for example: `--dot-server dns.google`, `--name-servers 1.1.1.1,8.8.8.8`, if both are specified, DoT server takes precedence. +9. Simple Web UI can be accessed from the same port of the proxy server, DNS servers and tunnel connection can be configured through the Web UI. Examples -------- @@ -85,62 +91,58 @@ Examples ![omnip](https://github.com/neevek/omnip/raw/master/omnip2.jpg) ``` -USAGE: - omnip [OPTIONS] --addr - -OPTIONS: - -a, --addr - Server address [://][ip:]port for - example: http://127.0.0.1:8000, http+quic://127.0.0.1:8000 - - -u, --upstream - upstream which the proxy server will relay traffic to based on proxy rules, - [://][ip|domain]:port for example: http://127.0.0.1:8000, - http+quic://127.0.0.1:8000 [default: ] - - -r, --proxy-rules-file - Path to the proxy rules file [default: ] - - -t, --threads - Threads to run async tasks, default to number of cpu cores [default: 0] - - --dot-server - DoT (DNS-over-TLS) server, e.g. dns.google [default: ] - - --name-servers - comma saprated domain servers (E.g. 1.1.1.1,8.8.8.8), which will be used if no - dot_server is specified, or system default if empty [default: ] - - -c, --cert - Applicable only for +quic protocols Path to the certificate file, if - empty, a self-signed certificate with the domain "localhost" will be used [default: ] - - -k, --key - Applicable only for +quic protocols Path to the key file, can be empty if - no cert is provided [default: ] - - -p, --password - Applicable only for +quic protocols Password of the +quic server [default: ] - - -e, --cipher - Applicable only for +quic protocols Password of the +quic server [default: - chacha20-poly1305] [possible values: chacha20-poly1305, aes-256-gcm, aes-128-gcm] - - -i, --max-idle-timeout-ms - Applicable only for quic protocol as upstream Max idle timeout for the QUIC - connections [default: 120000] - - -w, --watch-proxy-rules-change - reload proxy rules if updated - - -l, --loglevel - [default: I] [possible values: T, D, I, W, E] - - -h, --help - Print help information - - -V, --version - Print version information +Usage: omnip [OPTIONS] --addr + +Options: + -a, --addr + Server address [://][ip:]port + for example: http://127.0.0.1:8000, http+quic://127.0.0.1:8000 + -u, --upstream + Upstream which the proxy server will relay traffic to based on proxy rules, + [://]ip:port for example: http://127.0.0.1:8000, http+quic://127.0.0.1:8000 [default: ] + -r, --proxy-rules-file + Path to the proxy rules file [default: ] + -t, --threads + Threads to run async tasks, default to number of cpu cores [default: 0] + --dot-server + DoT (DNS-over-TLS) server, e.g. dns.google [default: ] + --name-servers + comma saprated domain servers (E.g. 1.1.1.1,8.8.8.8), which will be used + if no dot_server is specified, or system default if empty [default: ] + -c, --cert + Applicable only for +quic protocols + Path to the certificate file, if empty, a self-signed certificate + with the domain "localhost" will be used [default: ] + -k, --key + Applicable only for +quic protocols + Path to the key file, can be empty if no cert is provided [default: ] + -p, --password + Applicable only for +quic protocols + Password of the +quic server [default: ] + -e, --cipher + Applicable only for +quic protocols + Cipher for encryption [default: chacha20-poly1305] [possible values: chacha20-poly1305, aes-256-gcm, aes-128-gcm] + -i, --max-idle-timeout-ms + Applicable only for quic protocol as upstream + Max idle timeout for the QUIC connections [default: 120000] + -R, --retry-interval-ms + Applicable only for quic protocol as upstream + Max idle timeout for the QUIC connections [default: 5000] + --tcp-nodelay + Set TCP_NODELAY + -w, --watch-proxy-rules-change + Reload proxy rules if updated + -l, --loglevel + Log level [default: I] [possible values: T, D, I, W, E] + -E, --encode-base64 + Print the args as base64 string to be used in opp:// address, will be ignored if passing in + as an opp:// address, which can combine all args as a single base64 string + -D, --decode-base64 + Decode and print the base64 encoded opp:// address + -h, --help + Print help + -V, --version + Print version ``` License diff --git a/src/bin/omnip.rs b/src/bin/omnip.rs index 6f20e3f..3b73c37 100644 --- a/src/bin/omnip.rs +++ b/src/bin/omnip.rs @@ -106,12 +106,12 @@ fn print_args_as_base64(args: &OmnipArgs) -> bool { struct OmnipArgs { /// Server address [://][ip:]port /// for example: http://127.0.0.1:8000, http+quic://127.0.0.1:8000 - #[arg(short = 'a', long, required = true)] + #[arg(short = 'a', long, verbatim_doc_comment, required = true)] addr: String, /// Upstream which the proxy server will relay traffic to based on proxy rules, /// [://]ip:port for example: http://127.0.0.1:8000, http+quic://127.0.0.1:8000 - #[arg(short = 'u', long, default_value = "")] + #[arg(short = 'u', long, verbatim_doc_comment, default_value = "")] upstream: String, /// Path to the proxy rules file @@ -128,39 +128,39 @@ struct OmnipArgs { /// comma saprated domain servers (E.g. 1.1.1.1,8.8.8.8), which will be used /// if no dot_server is specified, or system default if empty - #[arg(long, default_value = "")] + #[arg(long, verbatim_doc_comment, default_value = "")] name_servers: String, /// Applicable only for +quic protocols /// Path to the certificate file, if empty, a self-signed certificate /// with the domain "localhost" will be used - #[arg(short = 'c', long, default_value = "")] + #[arg(short = 'c', long, verbatim_doc_comment, default_value = "")] cert: String, /// Applicable only for +quic protocols /// Path to the key file, can be empty if no cert is provided - #[arg(short = 'k', long, default_value = "")] + #[arg(short = 'k', long, verbatim_doc_comment, default_value = "")] key: String, /// Applicable only for +quic protocols /// Password of the +quic server - #[arg(short = 'p', long, default_value = "")] + #[arg(short = 'p', long, verbatim_doc_comment, default_value = "")] password: String, /// Applicable only for +quic protocols /// Cipher for encryption - #[arg(short = 'e', long, default_value_t = String::from(rstun::SUPPORTED_CIPHER_SUITE_STRS[0]), + #[arg(short = 'e', long, verbatim_doc_comment, default_value_t = String::from(rstun::SUPPORTED_CIPHER_SUITE_STRS[0]), value_parser = PossibleValuesParser::new(rstun::SUPPORTED_CIPHER_SUITE_STRS).map(|v| v.to_string()))] cipher: String, /// Applicable only for quic protocol as upstream /// Max idle timeout for the QUIC connections - #[arg(short = 'i', long, default_value = "120000")] + #[arg(short = 'i', long, verbatim_doc_comment, default_value = "120000")] max_idle_timeout_ms: u64, /// Applicable only for quic protocol as upstream /// Max idle timeout for the QUIC connections - #[arg(short = 'R', long, default_value = "5000")] + #[arg(short = 'R', long, verbatim_doc_comment, default_value = "5000")] retry_interval_ms: u64, /// Set TCP_NODELAY @@ -185,7 +185,7 @@ struct OmnipArgs { /// Print the args as base64 string to be used in opp:// address, will be ignored if passing in /// as an opp:// address, which can combine all args as a single base64 string - #[arg(short = 'E', long, action)] + #[arg(short = 'E', long, verbatim_doc_comment, action)] encode_base64: bool, /// Decode and print the base64 encoded opp:// address