# 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.
This allows creating a sort of VPN server without root access, e.g. from Android app or when using unprivileged containers.
## Features
* Maintaining Wireguard connection with one peer, using [Boringtun](https://github.com/cloudflare/boringtun) library.
* Decoding incoming TCP or UDP connections using [smoltcp](https://github.com/smoltcp-rs/smoltcp) library
* Forwarding TCP and UDP connections from Wireguard to external world, exchanging traffic userspace and real sockets.
* For UDP, hole punching / NAT traversal should work (not tested though)
* For TCP, half-closed connections and backpressure should work
* Crude DNS server for resolving IPv4 and IPv6 addresses using host DNS implementation
## Limitations
* No ICMP (except of pings to specific address for testing). This affects UDP's "port unreachable"s.
## 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$ RUST_LOG=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 handshake_initiation
DEBUG boringtun::noise: Received handshake_response local_idx=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: icmp_seq=1 ttl=64 time=0.705 ms
64 bytes from 192.168.72.2: icmp_seq=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/
...