Giter VIP home page Giter VIP logo

moproxy's Introduction

moproxy

A transparent TCP to SOCKSv5/HTTP proxy on Linux written in Rust.

Features:

  • Transparent TCP proxy with iptables -j REDIRECT or nft redirect to
  • Downstream SOCKSv5 as a supplement to transparent proxy
  • Multiple SOCKSv5/HTTP upstream proxy servers
  • SOCKS/HTTP-layer alive & latency probe for upstreams
  • Prioritize upstreams according to connection quality (latency & error rate)
  • Full IPv6 support
  • Proxy selection policy (see conf/policy.rules)
  • Multiple downstream listen ports (for proxy selection policy)
  • Remote DNS resolving for TLS with SNI (extract domain name from TLS handshaking)
  • Optional try-in-parallel for TLS (try multiple proxies and choose the one first response)
  • Optional status web page (latency, traffic, etc. w/ curl-friendly output)
  • Optional Graphite and OpenMetrics (Prometheus) support (to build fancy dashboard with Grafana for example)
  • Customizable proxy selection algorithm with Lua script (see conf/simple_scroe.lua).
+-----+  TCP  +-----------+       SOCKSv5   +---------+
| App |------>| firewall  |    +----------->| Proxy 1 |--->
+-----+       +-----------+    |            +---------+
            redirect |         |
+-----+           to v         |      HTTP  +---------+
| App |       //=========\\    |   +------->| Proxy 2 |--->
+-----+       ||         ||----+   |        +---------+
   |          || MOPROXY ||--------+             :
   +--------->||         ||-----------···        :
   SOCKSv5    \\=========//  Selection  |   +---------+
                          |  policy     +-->| Proxy N |--->
                          |                 +---------+
                          |
                          +----------- Direct ------------>

Breaking changes

There are CLI and/or configure changes among:

See MIGRATION.md

Usage

Print usage

moproxy --help

Examples

Assume there are three SOCKSv5 servers on localhost:2001, localhost:2002, and localhost:2003, and two HTTP proxy servers listen on localhost:3128 and 192.0.2.0:3128. Following commands forward all TCP connections that connect to 80 and 443 to these proxy servers.

moproxy --port 2080 --socks5 2001 2002 2003 --http 3128 192.0.2.0:3128

# redirect local-initiated connections
nft add rule nat output tcp dport {80, 443} redirect to 2080
# redirect connections initiated by other hosts (if you are router)
nft add rule nat prerouting tcp dport {80, 443} redirect to 2080

# or the legacy iptables equivalent
iptables -t nat -A OUTPUT -p tcp -m multiport --dports 80,443 -j REDIRECT --to-port 2080
iptables -t nat -A PREROUTING -p tcp -m multiport --dports 80,443 -j REDIRECT --to-port 2080

SOCKSv5 server is also launched alongs with transparent proxy on the same port:

http_proxy=socks5h://localhost:2080 curl ifconfig.co

Server list file

Put upstream proxies on a file to avoid messy CLI arguments and enable features like priority (score base), username/password auth, capabilities, etc.

See proxy.ini example for details.

Pass file path to moproxy via --list argument.

Signal SIGHUP will trigger the program to reload the list.

Proxy selection policy file

Let specified connections use only a subset of upstream proxies.

See policy.rules example for details.

Pass file path to moproxy via --policy argument.

Signal SIGHUP will trigger the program to reload the list.

Custom proxy selection

Proxy servers are sorted by their score, which is re-calculated after each round of alive/latency probing. Server with lower score is prioritized.

The current scoring algorithm is a kind of weighted moving average of latency with penalty for recent connection errors. This can be replaced with your own algorithm written in Lua. See conf/simple_score.lua for details.

Source/destination address–based proxy selection is not directly supported. One workaround is let moproxy bind multiple ports, delegates each port to different proxy servers with listen ports in your config, then doing address-based selection on your firewall.

Monitoring

Metrics (latency, traffic, number of connections, etc.) are useful for diagnosis and customing your own proxy selection. You can access these metrics with various methods, from a simple web page, curl, to specialized tools like Graphite or Prometheus.

--stats-bind [::1]:8080 turns on the internal stats page, via HTTP, on the given IP address and port number. It returns a HTML page for web browser, or a ASCII table for curl.

The stats page only provides current metrics and a few aggregations. Graphite (via --graphite) or OpenMetrics (via --stats-bind then \metrics) should be used if you want a full history.

Some examples of Prometheus query (Grafana variant):

Inbound bandwith:
rate(moproxy_proxy_server_bytes_rx_total[$__range])

Total outbound traffic:
sum(increase(moproxy_proxy_server_bytes_tx_total[$__range]))

No. of connection errors per minute:
sum(increase(moproxy_proxy_server_connections_error[1m]))

Average delay for each proxy server:
avg_over_time(moproxy_proxy_server_dns_delay_seconds[$__interval])

Systemd integration

Sample service file: conf/moproxy.service

Implemented features:

  • Watchdog
  • Reloading (via SIGHUP signal)
  • Notify (type=notify, reloading, status string)

Get simple status without turing on the HTTP stats page:

$ systemctl status moproxy
> ...
> Status: "serving (7/11 upstream proxies up)"
> ...

Install

You may download the binary executable file on releases page.

Arch Linux user can install it from AUR/moproxy.

Or compile it manually:

# Install Rust
curl https://sh.rustup.rs -sSf | sh

# Clone source code
git clone https://github.com/sorz/moproxy
cd moproxy

# Build
cargo build --release
target/release/moproxy --help

# If you are in Debian
cargo install cargo-deb
cargo deb
sudo dpkg -i target/debian/*.deb
moproxy --help

Refer to conf/ for config & systemd service files.

moproxy's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

moproxy's Issues

error: unexpected argument 'xxxx' found

when i used command :
moproxy --port 10080 --socks5 10081 10082

error info

moproxy --port 10080 --socks5 10081 10082
error: unexpected argument '10082' found
Usage: moproxy [OPTIONS] --port ...
For more information, try '--help'.

QQ截图20230313105759

info
moproxy 0.4.1
Microsoft Windows 11 Pro

setup blacklist and whitelist

i want all traffic pass through direct connection expect some domains (like Privoxy program)
Example:

*     direct
*.test.com   proxy
*.test2.org   proxy
cdn.test2.org direct

Idea: text/plain output for lynx/curl

It's great that I can run keep a tab open with the current moproxy status, but it would be even better to easily grab to optionally grab this status from the command line.

When you look at this window:
image

Most of the same output would make sense in the console.
Perhaps if the User-agent is Lynx or Curl, you could just output the same chart in plain text, and if we want to keep it refreshed, we can just run watch it whenever we start to see problems.

`all proxy server down` when using `trojan` as socks backend

When I try to run curl on with moproxy setup with a single trojan socks5 backend, I'm getting:

 ❯❯❯ curl -i -4 -vvv www.duckduckgo.com
*   Trying 176.34.155.23:80...
* TCP_NODELAY set
* Connected to www.duckduckgo.com (176.34.155.23) port 80 (#0)
> GET / HTTP/1.1
> Host: www.duckduckgo.com
> User-Agent: curl/7.65.1
> Accept: */*
> 
* Recv failure: Connection reset by peer
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer

When I check the moproxy log, I see this as the curl is executed:

[DEBUG] incoming 192.168.1.100:54986
[DEBUG] dest V4(176.34.155.23:80)
[TRACE] registering with poller
[DEBUG] connected with Ok(V4(127.0.0.1:2001))
[INFO] connect proxy error: early eof
[TRACE] deregistering handle with poller
[WARN] all proxy server down

When I check the trojan socks5 proxy log, I see:

Jul 06 22:35:11 ryxps trojan[7641]: [2019-07-06 22:35:11] [ALL] 127.0.0.1:56210 incoming connection
Jul 06 22:35:11 ryxps trojan[7641]: [2019-07-06 22:35:11] [ERROR] 127.0.0.1:56210 unknown protocol
Jul 06 22:35:11 ryxps trojan[7641]: [2019-07-06 22:35:11] [INFO] 127.0.0.1:56210 disconnected, 0 bytes received, 0 bytes sent, lasted for 0 seconds

Due to the timing of these in the logs, it seems definitive that iptables is forwarding my connection request to moproxy and through to my backend socks proxy, but the formatting of the request when moproxy provides it doesn't seem to be working for my socks proxy.

I followed the redsocks method for creating the iptables rule, but also an exception so that anything running as uid = proxy would not get redirected to moproxy.

my iptables rules
 ❯❯❯ iptables -t nat -A MOPROXY -d 0.0.0.0/8 -j RETURN                                                                                            
                                                                                                                                                   
 ❯❯❯ iptables -t nat -A MOPROXY -d 10.0.0.0/8 -j RETURN                 

 ❯❯❯ iptables -t nat -A MOPROXY -d 100.64.0.0/10 -j RETURN              

 ❯❯❯ iptables -t nat -A MOPROXY -d 127.0.0.0/8 -j RETURN                

 ❯❯❯ iptables -t nat -A MOPROXY -d 127.0.0.0/8 -j RETURN                

 ❯❯❯ iptables -t nat -A MOPROXY -d 169.254.0.0/16 -j RETURN             

 ❯❯❯ iptables -t nat -A MOPROXY -d 172.16.0.0/12 -j RETURN              

 ❯❯❯ iptables -t nat -A MOPROXY -d 192.168.0.0/16 -j RETURN

 ❯❯❯ iptables -t nat -A MOPROXY -d 198.18.0.0/15 -j RETURN

 ❯❯❯ iptables -t nat -A MOPROXY -d 224.0.0.0/4 -j RETURN

 ❯❯❯ iptables -t nat -A MOPROXY -d 240.0.0.0/4 -j RETURN

 ❯❯❯ iptables -t nat -A MOPROXY -p tcp -m owner ! --uid-owner proxy -j REDIRECT --to-ports 2080

 ❯❯❯ iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner proxy -j MOPROXY

Any tips on how to further debug this?

Note, running on Arch Linux (rolling release) with a stock kernel and all packages updated to current.

Delay calculation

Hi,

I'm struggling to get the delay calculation to work reliably.
Most of the time it doesn't have a value for any of the downstream proxies but occasionally it pops up for some of them.

In proxy.ini I have proxies defined like this (IP addresses obscured):

[89.XX.YY.49]
address=89.XX.YY.49:5360
protocol=http
http username = ********
http password = *********
max wait=3
test dns=1.1.1.1:53

Is there anything else I need to do to get delay scores generate?

I'm using simple_score.lua with it's debug on which confirms that delay is nil, as shown in the webstats.

/usr/local/bin/moproxy -b 10.168.1.1 -p 2080 --list /etc/moproxy/proxy.ini --stats-bind 0.0.0.0:8080

What am I missing?

Thx

Upstream Socks Authentication

Would you be able to add support for upstream socks5 authentication? I'm interested in using this to load balance/roundrobin between a number of upstream socks5 servers, they require authentication.

Thanks 👍

[Feature suggestion] UDP transparent proxy for SOCKS5 (TPROXY)

Here I use another program for UDP transparent proxying, but it doesn't work with LD_PRELOAD, so a Rust program for doing that is what I'm looking for.

It would be a good idea to implement support for UDP transparent proxy because many censorship solutions such as Shadowsocks, VMess, Vless and so on support UDP.

This project could serve as a basis for this implementation: https://github.com/MengJiangProject/redproxy-rs/search?q=tproxy

/\ Another thing that must be done is using the SOCKS5 command 03, for UDP ASSOCIATE.

It's my suggestion.

[Feature Request] relay HTTP request to upstream proxy without CONNECT

Hi,

My corporate proxy does not allow using CONNECT to establish connections to port 80, but requires cleartext HTTP proxy requests.

Can connections to port 80 be checked for HTTP correctness, and be proxied as GET/POST/PUT/xxx requests to the upstream HTTP proxy.

I have used, in a similar context, redsocks to achieve such redirections from a Docker for Windows environment, with two chains: one for port 80 to the http_relay module, the other for the rest to the http_connect module.

See:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.