tun2socks
A tun2socks powered by gVisor TCP/IP stack.
## Features
- ICMP echoing
- IPv6 support
- Optimized UDP transmission for game acceleration
- Pure Go implementation, no more CGO required
- Router mode, routing all the traffic in LAN
- Socks5, Shadowsocks protocol support for remote connections
- TCP/IP stack powered by [gVisor](https://github.com/google/gvisor)
- Up to 2.5Gbps throughput (10x faster than [v1](https://github.com/xjasonlyu/tun2socks/tree/v1))
## Requirements
| Target | Minimum | Recommended |
| :----- | :-----: | :---------: |
| System | linux darwin freebsd openbsd | linux |
| Memory | >20MB | >128MB |
| CPU | amd64 arm64 | amd64 |
## Performance
> iPerf3 tested on Debian 10 with i5-10500, 8G RAM
## How to Build
### build from source code
Go compiler version >= 1.15 is required
```text
$ git clone https://github.com/xjasonlyu/tun2socks.git
$ cd tun2socks
$ make
```
### build docker image
```text
$ docker build -t tun2socks .
```
or
```text
$ docker build -t tun2socks -f .Dockerfile.aarch64 .
```
## QuickStart
Download from precompiled [Releases](https://github.com/xjasonlyu/tun2socks/releases).
With Docker
> Since Go 1.12, the runtime now uses MADV_FREE to release unused memory on **linux**. This is more efficient but may result in higher reported RSS. The kernel will reclaim the unused data when it is needed. To revert to the Go 1.11 behavior (MADV_DONTNEED), set the environment variable GODEBUG=madvdontneed=1.
### create docker network (macvlan mode)
```shell script
docker network create -d macvlan \
--subnet=172.20.1.0/25 \
--gateway=172.20.1.1 \
-o parent=eth0 \
switch
```
### pull `tun2socks` docker image
```shell script
docker pull xjasonlyu/tun2socks:latest
```
### run as gateway
> DNS configuration is required.
```shell script
docker run -d \
--network switch \
--name tun2socks \
--ip 172.20.1.2 \
--privileged \
--restart always \
--sysctl net.ipv4.ip_forward=1 \
-e PROXY=socks5://server:port \
-e KEY=VALUE... \
xjasonlyu/tun2socks:latest
```
### use docker-compose (recommended)
```yaml
version: '2.4'
services:
tun2socks:
image: xjasonlyu/tun2socks:latest
cap_add:
- NET_ADMIN
devices:
- '/dev/net/tun:/dev/net/tun'
environment:
# - GODEBUG=madvdontneed=1
- PROXY=socks5://server:port
- LOGLEVEL=INFO
- API=api://:8080
- DNS=dns://:53
- HOSTS=localhost=127.0.0.1,router.local=172.20.1.1
- EXCLUDED=1.1.1.1,1.0.0.1
- EXTRACMD=
networks:
switch:
ipv4_address: 172.20.1.2
restart: always
container_name: tun2socks
networks:
switch:
name: switch
ipam:
driver: default
config:
- subnet: '172.20.1.0/25'
gateway: 172.20.1.1
driver: macvlan
driver_opts:
parent: eth0
```
With Linux
### create tun
```shell script
ip tuntap add mode tun dev tun0
ip addr add 198.18.0.1/15 dev tun0
ip link set dev tun0 up
```
### config policy routing
```shell script
echo "100 tun2socks" >> /etc/iproute2/rt_tables
ip route add default via 198.18.0.1 dev tun0 table tun2socks
ip route add 172.17.0.0/16 dev eth0 src 172.17.0.3 table tun2socks
ip route add 198.18.0.0/15 dev tun0 src 198.18.0.1 table tun2socks
ip rule add from 172.20.0.3 to 198.18.0.0/15 priority 1000 prohibit
ip rule add from 172.20.0.3 priority 2000 table main
ip rule add from all priority 3000 table tun2socks
```
### run
> bind to a specific interface to prevent traffic looping.
```shell script
./tun2socks --loglevel info --device tun://tun0 --proxy socks5://server:port --interface eth0
```
With MacOS
### start tun2socks
```shell script
./tun2socks --loglevel info --device tun://utun123 --proxy socks5://server:port --interface eth0
```
### config interface
```shell script
sudo ifconfig utun123 198.18.0.1 netmask 255.255.255.255 198.18.0.1 up
```
### config route
```shell script
sudo route del default
sudo route add default 198.18.0.1
sudo route add ${proxy_server_ip} ${your_gateway}
```
### check route table
```shell script
netstat -nr
```
With Script
> entrypoint.sh would take care of tun & routes.
```shell script
PROXY=socks5://server:port LOGLEVEL=INFO sh ./scripts/entrypoint.sh
```
## Details
API Reference
| Path | Methods | Parameters | Description |
| :--- | :------ | :--------: | :---------- |
| `/logs` | GET | `level` | Get real-time logs |
| `/traffic` | GET | / | Get real-time traffic data |
| `/version` | GET | / | Get current version |
| `/connections` | GET | `interval` | Get all connections |
| `/connections` | DELETE | / | Close all connections |
| `/connections/{id}` | DELETE | / | Close connection by `id` |
Help Text
```text
Usage of tun2socks:
-d, --device string Use this device [driver://]name
-i, --interface string Use network INTERFACE (Darwin/Linux only)
-l, --loglevel string Log level [debug|info|warn|error|silent] (default "info")
-m, --mtu int Maximum transmission unit
-p, --proxy string Use this proxy [protocol://]host[:port]
--stats string HTTP statistic server listen address
--token string HTTP statistic server auth token
-v, --version Show version information and quit
```
Proxy URL
| Protocol | Scheme | Examples |
| :------- | :----- | :------- |
| direct | `direct` | `direct://` |
| socks5 | `socks5` | `socks5://username:password@server:port` |
| shadowsocks | `ss`, `shadowsocks` | `ss://method:password@server:port` |
## Credits
- [Dreamacro/clash](https://github.com/Dreamacro/clash)
- [google/gvisor](https://github.com/google/gvisor)
- [majek/slirpnetstack](https://github.com/majek/slirpnetstack)
- [WireGuard/wireguard-go](https://github.com/WireGuard/wireguard-go)
## Known Issues
Due to the implementation of pure Go, the memory usage is higher than the previous version.
If you are sensitive to memory, please go back to [v1](https://github.com/xjasonlyu/tun2socks/tree/v1).
## TODO
- [x] Windows support
- [x] FreeBSD support
- [x] OpenBSD support