wireproxy

package module
v0.0.0-...-9a4bdbe Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2023 License: ISC Imports: 23 Imported by: 0

README

wireproxy

ISC licensed Build status Documentation

A wireguard client that exposes itself as a socks5/http proxy or tunnels.

What is this

wireproxy is a completely userspace application that connects to a wireguard peer, and exposes a socks5/http proxy or tunnels on the machine. This can be useful if you need to connect to certain sites via a wireguard peer, but can't be bothered to setup a new network interface for whatever reasons.

Why you might want this

  • You simply want to use wireguard as a way to proxy some traffic.
  • You don't want root permission just to change wireguard settings.

Currently, I'm running wireproxy connected to a wireguard server in another country, and configured my browser to use wireproxy for certain sites. It's pretty useful since wireproxy is completely isolated from my network interfaces, and I don't need root to configure anything.

Feature

  • TCP static routing for client and server
  • SOCKS5/HTTP proxy (currently only CONNECT is supported)

TODO

  • UDP Support in SOCKS5
  • UDP static routing

Usage

./wireproxy -c [path to config]
usage: wireproxy [-h|--help] [-c|--config "<value>"] [-s|--silent]
                 [-d|--daemon] [-v|--version] [-n|--configtest]

                 Userspace wireguard client for proxying

Arguments:

  -h  --help        Print help information
  -c  --config      Path of configuration file
  -s  --silent      Silent mode
  -d  --daemon      Make wireproxy run in background
  -v  --version     Print version
  -n  --configtest  Configtest mode. Only check the configuration file for
                    validity.

Build instruction

git clone https://github.com/octeep/wireproxy
cd wireproxy
make

Use with VPN

Instructions for using wireproxy with Firefox container tabs and auto-start on MacOS can be found here.

Sample config file

# The [Interface] and [Peer] configurations follow the same semantics and meaning
# of a wg-quick configuration. To understand what these fields mean, please refer to:
# https://wiki.archlinux.org/title/WireGuard#Persistent_configuration
# https://www.wireguard.com/#simple-network-interface
[Interface]
Address = 10.200.200.2/32 # The subnet should be /32 and /128 for IPv4 and v6 respectively
# MTU = 1420 (optional)
PrivateKey = uCTIK+56CPyCvwJxmU5dBfuyJvPuSXAq1FzHdnIxe1Q=
DNS = 10.200.200.1

[Peer]
PublicKey = QP+A67Z2UBrMgvNIdHv8gPel5URWNLS4B3ZQ2hQIZlg=
# PresharedKey = UItQuvLsyh50ucXHfjF0bbR4IIpVBd74lwKc8uIPXXs= (optional)
Endpoint = my.ddns.example.com:51820
# PersistentKeepalive = 25 (optional)

# TCPClientTunnel is a tunnel listening on your machine,
# and it forwards any TCP traffic received to the specified target via wireguard.
# Flow:
# <an app on your LAN> --> localhost:25565 --(wireguard)--> play.cubecraft.net:25565
[TCPClientTunnel]
BindAddress = 127.0.0.1:25565
Target = play.cubecraft.net:25565

# TCPServerTunnel is a tunnel listening on wireguard,
# and it forwards any TCP traffic received to the specified target via local network.
# Flow:
# <an app on your wireguard network> --(wireguard)--> 172.16.31.2:3422 --> localhost:25545
[TCPServerTunnel]
ListenPort = 3422
Target = localhost:25545

# STDIOTunnel is a tunnel connecting the standard input and output of the wireproxy
# process to the specified TCP target via wireguard.
# This is especially useful to use wireproxy as a ProxyCommand parameter in openssh
# For example:
#    ssh -o ProxyCommand='wireproxy -c myconfig.conf' ssh.myserver.net
# Flow:
# Piped command -->(wireguard)--> ssh.myserver.net:22
[STDIOTunnel]
Target = ssh.myserver.net:22

# Socks5 creates a socks5 proxy on your LAN, and all traffic would be routed via wireguard.
[Socks5]
BindAddress = 127.0.0.1:25344

# Socks5 authentication parameters, specifying username and password enables
# proxy authentication.
#Username = ...
# Avoid using spaces in the password field
#Password = ...

# http creates a http proxy on your LAN, and all traffic would be routed via wireguard.
[http]
BindAddress = 127.0.0.1:25345

# HTTP authentication parameters, specifying username and password enables
# proxy authentication.
#Username = ...
# Avoid using spaces in the password field
#Password = ...

Alternatively, if you already have a wireguard config, you can import it in the wireproxy config file like this:

WGConfig = <path to the wireguard config>

# Same semantics as above
[TCPClientTunnel]
...

[TCPServerTunnel]
...

[Socks5]
...

Having multiple peers is also supported. AllowedIPs would need to be specified such that wireproxy would know which peer to forward to.

[Interface]
Address = 10.254.254.40/32
PrivateKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=

[Peer]
Endpoint = 192.168.0.204:51820
PublicKey = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY=
AllowedIPs = 10.254.254.100/32
PersistentKeepalive = 25

[Peer]
PublicKey = ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ=
AllowedIPs = 10.254.254.1/32, fdee:1337:c000:d00d::1/128
Endpoint = 172.16.0.185:44044
PersistentKeepalive = 25


[TCPServerTunnel]
ListenPort = 5000
Target = service-one.servicenet:5000

[TCPServerTunnel]
ListenPort = 5001
Target = service-two.servicenet:5001

[TCPServerTunnel]
ListenPort = 5080
Target = service-three.servicenet:80

Wireproxy can also allow peers to connect to it:

[Interface]
ListenPort = 5400
...

[Peer]
PublicKey = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY=
AllowedIPs = 10.254.254.100/32
# Note there is no Endpoint defined here.

Stargazers over time

Stargazers over time

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseInterface

func ParseInterface(cfg *ini.File, device *DeviceConfig) error

ParseInterface parses the [Interface] section and extract the information into `device`

func ParsePeers

func ParsePeers(cfg *ini.File, peers *[]PeerConfig) error

ParsePeer parses the [Peer] section and extract the information into `peers`

func STDIOTcpForward

func STDIOTcpForward(vt *VirtualTun, raddr *addressPort)

STDIOTcpForward starts a new connection via wireguard and forward traffic from `conn`

func TCPAddrFromAddrPort

func TCPAddrFromAddrPort(addr netip.AddrPort) *net.TCPAddr

Types

type Configuration

type Configuration struct {
	Device   *DeviceConfig
	Routines []RoutineSpawner
}

func ParseConfig

func ParseConfig(path string) (*Configuration, error)

ParseConfig takes the path of a configuration file and parses it into Configuration

type CredentialValidator

type CredentialValidator struct {
	// contains filtered or unexported fields
}

CredentialValidator stores the authentication data of a socks5 proxy

func (CredentialValidator) Valid

func (c CredentialValidator) Valid(username, password string) bool

Valid checks the authentication data in CredentialValidator and compare them to username and password in constant time.

type DeviceConfig

type DeviceConfig struct {
	SecretKey  string
	Endpoint   []netip.Addr
	Peers      []PeerConfig
	DNS        []netip.Addr
	MTU        int
	ListenPort *int
}

DeviceConfig contains the information to initiate a wireguard connection

type DeviceSetting

type DeviceSetting struct {
	// contains filtered or unexported fields
}

DeviceSetting contains the parameters for setting up a tun interface

type HTTPConfig

type HTTPConfig struct {
	BindAddress string
	Username    string
	Password    string
}

func (*HTTPConfig) SpawnRoutine

func (config *HTTPConfig) SpawnRoutine(vt *VirtualTun)

SpawnRoutine spawns a http server.

type HTTPServer

type HTTPServer struct {
	// contains filtered or unexported fields
}

func (*HTTPServer) ListenAndServe

func (s *HTTPServer) ListenAndServe(network, addr string) error

ListenAndServe is used to create a listener and serve on it

type PeerConfig

type PeerConfig struct {
	PublicKey    string
	PreSharedKey string
	Endpoint     *string
	KeepAlive    int
	AllowedIPs   []netip.Prefix
}

type RoutineSpawner

type RoutineSpawner interface {
	SpawnRoutine(vt *VirtualTun)
}

RoutineSpawner spawns a routine (e.g. socks5, tcp static routes) after the configuration is parsed

type STDIOTunnelConfig

type STDIOTunnelConfig struct {
	Target string
}

func (*STDIOTunnelConfig) SpawnRoutine

func (conf *STDIOTunnelConfig) SpawnRoutine(vt *VirtualTun)

SpawnRoutine connects to the specified target and plumbs it to STDIN / STDOUT

type Socks5Config

type Socks5Config struct {
	BindAddress string
	Username    string
	Password    string
}

func (*Socks5Config) SpawnRoutine

func (config *Socks5Config) SpawnRoutine(vt *VirtualTun)

SpawnRoutine spawns a socks5 server.

type TCPClientTunnelConfig

type TCPClientTunnelConfig struct {
	BindAddress *net.TCPAddr
	Target      string
}

func (*TCPClientTunnelConfig) SpawnRoutine

func (conf *TCPClientTunnelConfig) SpawnRoutine(vt *VirtualTun)

SpawnRoutine spawns a local TCP server which acts as a proxy to the specified target

type TCPServerTunnelConfig

type TCPServerTunnelConfig struct {
	ListenPort int
	Target     string
}

func (*TCPServerTunnelConfig) SpawnRoutine

func (conf *TCPServerTunnelConfig) SpawnRoutine(vt *VirtualTun)

SpawnRoutine spawns a TCP server on wireguard which acts as a proxy to the specified target

type VirtualTun

type VirtualTun struct {
	Tnet      *netstack.Net
	SystemDNS bool
}

VirtualTun stores a reference to netstack network and DNS configuration

func StartWireguard

func StartWireguard(conf *DeviceConfig, logLevel int) (*VirtualTun, error)

StartWireguard creates a tun interface on netstack given a configuration

func (*VirtualTun) LookupAddr

func (d *VirtualTun) LookupAddr(ctx context.Context, name string) ([]string, error)

LookupAddr lookups a hostname. DNS traffic may or may not be routed depending on VirtualTun's setting

func (*VirtualTun) Resolve

func (d *VirtualTun) Resolve(ctx context.Context, name string) (net.IP, error)

Resolve resolves a hostname and returns an IP. DNS traffic may or may not be routed depending on VirtualTun's setting

func (*VirtualTun) ResolveAddrWithContext

func (d *VirtualTun) ResolveAddrWithContext(ctx context.Context, name string) (*netip.Addr, error)

ResolveAddrWithContext resolves a hostname and returns an AddrPort. DNS traffic may or may not be routed depending on VirtualTun's setting

type WireGuardTransport

type WireGuardTransport struct {
	Tnet      *netstack.Net
	SystemDNS bool
}

func (*WireGuardTransport) Dial

func (w *WireGuardTransport) Dial(ctx context.Context, network, addr string) (net.Conn, error)

func (*WireGuardTransport) LookupAddr

func (w *WireGuardTransport) LookupAddr(ctx context.Context, name string) ([]string, error)

func (*WireGuardTransport) Resolve

func (w *WireGuardTransport) Resolve(ctx context.Context, name string) (net.IP, error)

type WireProxy

type WireProxy struct {
	// contains filtered or unexported fields
}

func NewWireProxy

func NewWireProxy(config string) *WireProxy

func (*WireProxy) IsRunning

func (wp *WireProxy) IsRunning() bool

func (*WireProxy) SetSysProxy

func (wp *WireProxy) SetSysProxy(on bool)

func (*WireProxy) Start

func (wp *WireProxy) Start() error

func (*WireProxy) Stop

func (wp *WireProxy) Stop()

type Wireguard

type Wireguard struct {
	// contains filtered or unexported fields
}

func (*Wireguard) Close

func (w *Wireguard) Close() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL