wireproxy Documentation

Wireguard client that exposes itself as a socks5 proxy

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy wireproxy on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name wireproxy --restart always windtf/wireproxy:latest

Technical Documentation: windtf/wireproxy

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (`README.md`)

wireproxy



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.

Users who want something similar but for Amnezia VPN can use this fork
of wireproxy by @artem-russkikh.

Feature

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

TODO

  • UDP Support in SOCKS5
  • UDP static routing

Usage

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

                 Userspace wireguard client for proxying

Arguments:

  -h  --help        Print help information
  -c  --config      Path of configuration file
                    Default paths: /etc/wireproxy/wireproxy.conf, $HOME/.config/wireproxy.conf
  -s  --silent      Silent mode
  -d  --daemon      Make wireproxy run in background
  -i  --info        Specify the address and port for exposing health status
  -v  --version     Print version
  -n  --configtest  Configtest mode. Only check the configuration file for
                    validity.

Build instruction

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

Install

bash
go install github.com/windtf/wireproxy/cmd/[email protected] # or @latest

Use with VPN

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

Sample config file

text
/* Detailed source-code truncated for AI context efficiency. */

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

ini
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.

ini
[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

[UDPProxyTunnel]
BindAddress = 127.0.0.1:53
Target = 1.1.1.1:53
InactivityTimeout = 30 # If its set to 0, it will never timeout

[Resolve]
# Set DNS Resovle Strategy
# `ipv4`: Prioritize A records.
# `ipv6`: Prioritize AAAA records       .
# `auto` (Default): If the WireGuard interface has IPv4 address only, it's equivalent to `ipv4`, otherwise it's equivalent to `ipv6`.
ResolveStrategy = auto

Wireproxy can also allow peers to connect to it:

ini
[Interface]
ListenPort = 5400
...

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

Health endpoint

Wireproxy supports exposing a health endpoint for monitoring purposes.
The argument --info/-i specifies an address and port (e.g. localhost:9080), which exposes a HTTP server that provides health status metric of the server.

Currently two endpoints are implemented:

/metrics: Exposes information of the wireguard daemon, this provides the same information you would get with wg show. This shows an example of what the response would look like.

/readyz: This responds with a json which shows the last time a pong is received from an IP specified with CheckAlive. When CheckAlive is set, a ping is sent out to addresses in CheckAlive per CheckAliveInterval seconds (defaults to 5) via wireguard. If a pong has not been received from one of the addresses within the last CheckAliveInterval seconds (+2 seconds for some leeway to account for latency), then it would respond with a 503, otherwise a 200.

For example:

ini
[Interface]
PrivateKey = censored
Address = 10.2.0.2/32
DNS = 10.2.0.1
CheckAlive = 1.1.1.1, 3.3.3.3
CheckAliveInterval = 3

[Peer]
PublicKey = censored
AllowedIPs = 0.0.0.0/0
Endpoint = 149.34.244.174:51820

[Socks5]
BindAddress = 127.0.0.1:25344

/readyz would respond with

text
< HTTP/1.1 503 Service Unavailable
< Date: Thu, 11 Apr 2024 00:54:59 GMT
< Content-Length: 35
< Content-Type: text/plain; charset=utf-8
<
{"1.1.1.1":1712796899,"3.3.3.3":0}

And for:

ini
[Interface]
PrivateKey = censored
Address = 10.2.0.2/32
DNS = 10.2.0.1
CheckAlive = 1.1.1.1

/readyz would respond with

text
< HTTP/1.1 200 OK
< Date: Thu, 11 Apr 2024 00:56:21 GMT
< Content-Length: 23
< Content-Type: text/plain; charset=utf-8
<
{"1.1.1.1":1712796979}

If nothing is set for CheckAlive, an empty JSON object with 200 will be the response.

The peer which the ICMP ping packet is routed to depends on the AllowedIPs set for each peers.


Overview (`rc.d/README.md`)

Running wireproxy with rc.d

If you're on a rc.d-based distro, you'll most likely want to run Wireproxy as a systemd unit.

The provided systemd unit assumes you have the wireproxy executable installed on /bin/wireproxy and a configuration file stored at /etc/wireproxy.conf. These paths can be customized by editing the unit file.

Setting up the unit

  1. Copy the wireproxy file from this directory to /usr/local/etc/rc.d.

  2. If necessary, customize the unit.
    Edit the parts with procname, command, wireproxy_conf to point to the executable and the configuration file.

  3. Add the following lines to /etc/rc.conf to enable wireproxy
    wireproxy_enable="YES"

  4. Start wireproxy service and check status

    text
    sudo service wireproxy start
    sudo service wireproxy status

Overview (`systemd/README.md`)

Running wireproxy with systemd

If you're on a systemd-based distro, you'll most likely want to run Wireproxy as a systemd unit.

The provided systemd unit assumes you have the wireproxy executable installed on /opt/wireproxy/wireproxy and a configuration file stored at /etc/wireproxy.conf. These paths can be customized by editing the unit file.

Setting up the unit

  1. Copy the wireproxy.service file from this directory to /etc/systemd/system/, or use the following cURL command to download it:

    bash
    curl https://raw.githubusercontent.com/windtf/wireproxy/master/systemd/wireproxy.service | sudo tee /etc/systemd/system/wireproxy.service
  2. If necessary, customize the unit.

    Edit the parts with LoadCredential, ExecStartPre= and ExecStart= to point to the executable and the configuration file. For example, if wireproxy is installed on /usr/bin and the configuration file is located in /opt/myfiles/wireproxy.conf do the following change:

    service
    LoadCredential=conf:/opt/myfiles/wireproxy.conf
    ExecStartPre=/usr/bin/wireproxy -n -c ${CREDENTIALS_DIRECTORY}/conf
    ExecStart=/usr/bin/wireproxy -c ${CREDENTIALS_DIRECTORY}/conf
  3. Reload systemd and enable the unit.

    bash
    sudo systemctl daemon-reload
    sudo systemctl enable --now wireproxy.service
  4. Make sure it's working correctly.

    Finally, check out the unit status to confirm wireproxy.service has started without problems. You can use commands like systemctl status wireproxy.service and/or sudo journalctl -u wireproxy.service.

Additional notes

If you want to disable the extensive logging that's done by Wireproxy, simply add -s parameter to ExecStart=. This will enable the silent mode that was implemented with pull/67.


--- METRICS ---