wgslirpy

A command line tool (and a Rust library) for accepting incoming connections within a Wireguard link and routing them to external network using usual opeating system's socket API.

Diagram depicting operation of Wgslirpy

Features

Limitations

Demo session

Setup

``` peer# wg genkey 4Khaa5tgPI9NJsO2R896Yd6748k9fW4aapGZnIcUM14= peer# wg pubkey <<< 4Khaa5tgPI9NJsO2R896Yd6748k9fW4aapGZnIcUM14= rPpCjWzIv/yAtZZi+C/pVprie8D0QaGlPtJXlDi6bmI=

gateway$ wg genkey SG43Zi0wGp4emfJ/XpTnnmtnK8SSjjIHOc3Zh37c928= gateway$ wg pubkey <<< SG43Zi0wGp4emfJ/XpTnnmtnK8SSjjIHOc3Zh37c928= MR2RF5Tp+6BKt9k+deKg1GqR3re3ckJKti+uwZA84DU=

peer# ip link add wgslirpyspeer type wireguard peer# wg set wgslirpyspeer listen-port 9796 private-key <(echo 4Khaa5tgPI9NJsO2R896Yd6748k9fW4aapGZnIcUM14=) peer MR2RF5Tp+6BKt9k+deKg1GqR3re3ckJKti+uwZA84DU= allowed-ips 0.0.0.0/0,::/0 peer# ip netns add testing-wgslirp peer# ip link set wgslirpyspeer netns testing-wgslirp peer# ip netns exec testing-wgslirp ip link set wgslirpyspeer up peer# ip netns exec testing-wgslirp ip addr add 192.168.76.1/32 dev wgslirpyspeer peer# ip netns exec testing-wgslirp ip addr add fc00::01/128 dev wgslirpyspeer peer# ip netns exec testing-wgslirp route -4 add default dev wgslirpyspeer peer# ip netns exec testing-wgslirp route -6 add default dev wgslirpyspeer peer# mkdir -p /etc/netns/testing-wgslirp peer# echo nameserver 192.168.72.2 > /etc/netns/testing-wgslirp/resolv.conf ```

Activation

``` gateway$ RUSTLOG=debug wgslirpy --private-key SG43Zi0wGp4emfJ/XpTnnmtnK8SSjjIHOc3Zh37c928= -b 127.0.0.1:9797 --peer-key rPpCjWzIv/yAtZZi+C/pVprie8D0QaGlPtJXlDi6bmI= --keepalive-interval 10 --dns 192.168.72.2:53 --pingable 192.168.72.2 DEBUG boringtun::noise: Sending handshakeinitiation DEBUG boringtun::noise: Received handshakeresponse localidx=1 remote_idx=2743606023 DEBUG boringtun::noise: New session session=1 DEBUG boringtun::noise: Sending keepalive

peer# ip netns exec testing-wgslirp wg interface: wgslirpyspeer public key: rPpCjWzIv/yAtZZi+C/pVprie8D0QaGlPtJXlDi6bmI= private key: (hidden) listening port: 9796

peer: MR2RF5Tp+6BKt9k+deKg1GqR3re3ckJKti+uwZA84DU= endpoint: 127.0.0.1:9797 allowed ips: 0.0.0.0/0, ::/0 latest handshake: 46 seconds ago transfer: 340 B received, 92 B sent ```

Testing

``` peer# # ip netns exec testing-wgslirp ping -c 2 192.168.72.2 64 bytes from 192.168.72.2: icmpseq=1 ttl=64 time=0.705 ms 64 bytes from 192.168.72.2: icmpseq=2 ttl=64 time=0.435 ms

gateway$ INFO wgslirpy::router: New NAT entry for Pingable DEBUG wgslirpy::router: Finished serving Pingable

peer# ip netns exec testing-wgslirp curl http://example.com/ ...

gateway$ DEBUG wgslirpy::router::serve_dns: DNS query example.com:0 DEBUG wgslirpy::router: Sending DNS reply

INFO wgslirpy::router: New NAT entry for Tcp { clientside: Endpoint { addr: Ipv4(Address([192, 168, 76, 1])), port: 48004 }, externalside: Endpoint { addr: Ipv4(Address([93, 184, 216, 34])), port: 80 } } DEBUG wgslirpy::router::servetcp: Connected to upstream TCP DEBUG wgslirpy::router::servetcp: Accepted the connection DEBUG wgslirpy::router::servetcp: EOF received from client DEBUG wgslirpy::router::servetcp: Shutdown finished DEBUG wgslirpy::router::servetcp: EOF DEBUG wgslirpy::router::servetcp: Client TCP socket no longer active DEBUG boringtun::noise::timers: KEEPALIVE(PERSISTENTKEEPALIVE) DEBUG wgslirpy::router: Finished serving Tcp { clientside: Endpoint { addr: Ipv4(Address([192, 168, 76, 1])), port: 48004 }, external_side: Endpoint { addr: Ipv4(Address([93, 184, 216, 34])), port: 80 } }

peer# ip netns exec testing-wgslirp dig +short github.com @8.8.8.8 140.82.112.3

gateway$ 01:26:14 INFO wgslirpy::router: New NAT entry for Udp ... 01:27:46 DEBUG wgslirpy::router::serve_udp: Timed out a UDP connection ```

Installation

Download a pre-built executable from Github releases or install from source code with cargo install --path . or cargo install wgslirpy.

CLI options

wgslirpy --help output

``` Usage: wgslirpy [-k ] [-f ] -K [-p ] [-a ] -b [-D ] [-P ] [--mtu ] [--tcp-buffer-size ] [--transmit-queue-capacity ]

Expose internet access without root using Wireguard

Options: -k, --private-key main private key of this Wireguard node, base64-encoded -f, --private-key-file main private key of this Wireguard node (content of a specified file), base64-encoded -K, --peer-key peer's public key -p, --peer-endpoint address of the peer's UDP socket, where to send keepalives -a, --keepalive-interval keepalive interval, in seconds -b, --bind-ip-port where to bind our own UDP socket for Wireguard connection -D, --dns use this UDP socket address as a simple A/AAAA-only DNS server within Wireguard network -P, --pingable reply to ICMP pings on this single address within Wireguard network --mtu maximum transfer unit to use for TCP. Default is 1420. --tcp-buffer-size in-application socket TCP buffer size. Note that operating system socket buffer also applies. --transmit-queue-capacity nubmer of outgoing (to wireguard) packets to hold in a queue --help display usage information

```

See also