Coder Social home page Coder Social logo

wirez's Introduction

wirez

License Build Status GoReportCard Status

wirez can redirect all TCP/UDP traffic made by any given program (application, script, shell, etc.) to SOCKS5 proxy and block other IP traffic (ICMP, SCTP etc).

Compared with tsocks, proxychains or proxychains-ng, wirez is not using the LD_PRELOAD hack that only works for dynamically linked programs, e.g., applications built by Go can not be hooked by proxychains-ng.

Instead, wirez is based on the rootless container technology and the userspace network stack, that is much more robust and secure. See how does it work for more details.

Also, wirez can act as a simple SOCKS5 load balancer server.

demo.mp4


Installation

wirez is a cross-platform application. However, run subcommand is available only on Linux.

From source

From the root of the source tree, run:

go build

Quick Start

start bash shell and redirect all TCP and UDP traffic through socks5 proxy server that is listening on 127.0.0.1:1234 address:

wirez run -F 127.0.0.1:1234 bash

proxy a curl request to example.com:

wirez run -F 127.0.0.1:1234 -- curl example.com

By default, all UDP traffic is forwarded to SOCKS5 proxy using UDP ASSOCIATE request. If SOCKS5 proxy doesn't support this method (like ssh and Tor) you can use local port forwarding option -L. It specifies that connections to the target host and TCP/UDP port are to be directly forwarded to the given host and port.

For instance, forward all TCP traffic through proxy, but all UDP traffic directly to 1.1.1.1 DNS server:

wirez run -F 127.0.0.1:1234 -L 53:1.1.1.1:53/udp -- curl example.com

forward all TCP and UDP traffic through the proxy, but redirect TCP traffic targeted to 10.10.10.10:2345 directly to 127.0.0.1:4567:

wirez run -F 127.0.0.1:1234 -L 10.10.10.10:2345:127.0.0.1:4567/tcp bash

Load Balancing

Create a plain text file with one socks5 proxy per line. For demonstration purposes, here is an example file proxies.txt:

10.1.1.1:1035
10.2.2.2:1037

Start wirez on the localhost on port 1080:

wirez server -f proxies.txt -l 127.0.0.1:1080

Now every socks5 request on 1080 port will be load balanced between socks5 proxies in the proxies.txt file. Enjoy!

Usage

wirez help

How does it work?

First of all, run command creates a new unix socket pair for parent/child process communication.

fds, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)

After that we start a new child process in a new Linux user namespace, see user_namespaces(7):

proc.SysProcAttr = &syscall.SysProcAttr{
	Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWNET | syscall.CLONE_NEWUSER,
	...
}

Inside the new namespace, the child process has root capabilities, so we open a new tun network device:

tunFd, err := tun.Open(tunDevice)

and send this tun file descriptor to the parent process using the unix socket pair:

rights := unix.UnixRights(fd)
return unix.Sendmsg(c.socketFd, nil, rights, nil, 0)

in the parent process we receive this tun file descriptor:

func (c *parentUnixSocketConn) ReceiveFd() (fd int, err error) {
	// receive socket control message
	b := make([]byte, unix.CmsgSpace(4))
	if _, _, _, _, err = unix.Recvmsg(c.socketFd, nil, b, 0); err != nil {
		return
	}

	// parse socket control message
	cmsgs, err := unix.ParseSocketControlMessage(b)
	if err != nil {
		return 0, fmt.Errorf("parse socket control message: %w", err)
	}

	tunFds, err := unix.ParseUnixRights(&cmsgs[0])
	if err != nil {
		return 0, err
	}
	if len(tunFds) == 0 {
		return 0, errors.New("tun fds slice is empty")
	}
	return tunFds[0], nil
}

and initialize a gVisor userspace network stack on top of it. Then in the child process we set up the tun device as default IP gateway and, finally, start a target process specified in cli args. That's it!

License

This project is licensed under the MIT License. See the LICENSE file for the full license text.

wirez's People

Contributors

v-byte-cpu avatar

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

Watchers

 avatar  avatar  avatar

wirez's Issues

Android version?

Is there any chance of it working on modern (13-ish) android?

Authentication

Hi, can you add authentication support? I came here from mubeng and would like to try out your proxy rotator in the SOCKS5 Protocol.
socks5://USER[:PASS]@IP:PORT

Does not build anymore (gVisor API changes)

gVisor has changed its API, and the program doesn't build anymore:

ubuntu@server:~/wirez$ go build
package github.com/v-byte-cpu/wirez
        imports github.com/v-byte-cpu/wirez/command
        imports github.com/v-byte-cpu/wirez/pkg/connect
        imports gvisor.dev/gvisor/pkg/tcpip
        imports gvisor.dev/gvisor/pkg/atomicbitops
        imports gvisor.dev/gvisor/pkg/cpuid
        imports gvisor.dev/gvisor/pkg/state
        imports gvisor.dev/gvisor/pkg/state/wire
        imports gvisor.dev/gvisor/pkg/gohacks: build constraints exclude all Go files in /home/ubuntu/go/pkg/mod/gvisor.dev/[email protected]/pkg/gohacks

Used go version: go version go1.22.0 linux/arm64

Attempting to fix it by upgrading gVisor also does not work:

ubuntu@server:~/wirez$ GO111MODULE=on go get gvisor.dev/gvisor@go
go: added gvisor.dev/gvisor v0.0.0-20240301005136-96d748d5c7c5
ubuntu@server:~/wirez$ go build
# github.com/v-byte-cpu/wirez/pkg/connect
pkg/connect/network_stack.go:96:47: cannot convert ipNet.IP (variable of type net.IP) to type tcpip.Address
pkg/connect/network_stack.go:96:76: cannot convert ipNet.Mask (variable of type net.IPMask) to type tcpip.AddressMask
pkg/connect/network_stack.go:148:57: too many arguments in call to gonet.NewUDPConn
        have (*stack.Stack, *waiter.Queue, tcpip.Endpoint)
        want (*waiter.Queue, tcpip.Endpoint)

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.