{"id":31701901,"url":"https://github.com/getlantern/tunio","last_synced_at":"2026-03-16T15:40:25.739Z","repository":{"id":144926372,"uuid":"41496097","full_name":"getlantern/tunio","owner":"getlantern","description":"tunio forwards TCP packets to a net.Dialer","archived":false,"fork":false,"pushed_at":"2016-02-23T02:32:31.000Z","size":1661,"stargazers_count":23,"open_issues_count":7,"forks_count":8,"subscribers_count":20,"default_branch":"master","last_synced_at":"2024-04-15T03:25:53.615Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/getlantern.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-27T15:46:59.000Z","updated_at":"2023-03-21T12:35:58.000Z","dependencies_parsed_at":"2023-05-06T20:17:14.881Z","dependency_job_id":null,"html_url":"https://github.com/getlantern/tunio","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/getlantern/tunio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getlantern%2Ftunio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getlantern%2Ftunio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getlantern%2Ftunio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getlantern%2Ftunio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/getlantern","download_url":"https://codeload.github.com/getlantern/tunio/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getlantern%2Ftunio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000716,"owners_count":26082837,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-08T21:09:56.298Z","updated_at":"2025-10-08T21:10:00.291Z","avatar_url":"https://github.com/getlantern.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tunio\n\nThe `tunio` package captures and forwards raw TCP packets to a Go's\n[net.Dialer](https://golang.org/pkg/net/#Dialer) using a [TUN device][3].\n\n`tunio` is able to forward UDP packets as well, an external [badvpn-udpgw][4]\nserver is required.\n\n## How to compile and run?\n\nClone the source\n\n```\nmkdir -p $GOPATH/src/github.com/getlantern\ncd $GOPATH/src/github.com/getlantern\ngit clone https://github.com/getlantern/tunio.git\ncd tunio\n```\n\nBuild and run the docker container that provides the `badvpn-udpgw` +\n[Lantern][2] bundle:\n\n```\nmake -C scripts/server docker-run\n# ...\ndocker ps\n# ...\n# a6fca81fffee        getlantern/tunio-proxy   \"/usr/bin/start.sh\"   16 minutes ago      Up 16 minutes       0.0.0.0:2099-\u003e2099/tcp, 0.0.0.0:5353-\u003e5353/tcp   tunio-proxy\n# ...\n```\n\nUsing a docker container is fine for creating and running a proxy, but in order\nto work with tunio we need more room to experiment, let's create a full virtual\nmachine with centos-7.2:\n\n```\nmkdir -p ~/projects/tunio-vm\ncd ~/projects/tunio-vm\nvagrant init bento/centos-7.2\nvagrant up\n# ...\n```\n\nLog in into the newly created virtual machine and install some required\npackages:\n\n```sh\nvagrant ssh\nsudo yum install -y git gcc glibc-static\n\n# Go\ncurl --silent https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz \\\n\t| sudo tar -xzv -C /usr/local/\n\necho 'export GOROOT=/usr/local/go'    \u003e\u003e $HOME/.bashrc\necho 'export PATH=$PATH:$GOROOT/bin'  \u003e\u003e $HOME/.bashrc\necho 'export GOPATH=$HOME/go'         \u003e\u003e $HOME/.bashrc\n\nsource $HOME/.bashrc\n```\n\nClone the `tunio` package (again, into the vm) with `git` and change directory\nto the `tunio`'s source path:\n\n```sh\nmkdir -p $GOPATH/src/github.com/getlantern\ncd $GOPATH/src/github.com/getlantern\ngit clone https://github.com/getlantern/tunio.git\ncd tunio\n```\n\nCompile the `tunio` binary with:\n\n```sh\nmake binary\n```\n\nAfter this you should have a `tunio` binary on `$GOPATH/bin`.\n\nCreate a new TUN device, let's name it `tun0` and assign the `10.0.0.1` IP\naddress to it.\n\n```sh\nexport ORIGINAL_GW=$(ip route  | grep default | awk '{print $3}')\n\nexport DEVICE_NAME=tun0\nexport DEVICE_IP=10.0.0.1\n\nsudo ip tuntap del $DEVICE_NAME mode tun\nsudo ip tuntap add $DEVICE_NAME mode tun\nsudo ifconfig $DEVICE_NAME $DEVICE_IP netmask 255.255.255.0\n```\n\nReplace the virtual machine's name servers with 8.8.8.8 and 8.8.4.4.\n\n```\necho \"nameserver 8.8.8.8\" | sudo tee /etc/resolv.conf\necho \"nameserver 8.8.4.4\" | sudo tee -a /etc/resolv.conf\n```\n\nModify the routing table to only allow direct traffic with the proxy server\n(the docker host's IP)\n\n```sh\nexport PROXY_IP=10.0.0.66\n\nsudo route add $PROXY_IP gw $ORIGINAL_GW metric 5\nsudo route add default gw 10.0.0.2 metric 6\n```\n\nThat was a lot of stuff, you can also do all that by using this script:\n\n```\nPROXY_IP=10.0.0.66 make -C scripts/tunconfig up\n```\n\nIf everything is OK you should not be able to ping external hosts:\n\n```\nping google.com\nPING google.com (74.125.227.165) 56(84) bytes of data.\n^C\n--- google.com ping statistics ---\n5 packets transmitted, 0 received, 100% packet loss, time 4001ms\n```\n\nBut you should be able to ping `$PROXY_IP`.\n\n```\nping $PROXY_IP\nPING 10.0.0.66 (10.0.0.66) 56(84) bytes of data.\n64 bytes from 10.0.0.66: icmp_seq=1 ttl=63 time=3.45 ms\n64 bytes from 10.0.0.66: icmp_seq=2 ttl=63 time=0.403 ms\n^C\n--- 10.0.0.66 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1001ms\nrtt min/avg/max/mdev = 0.403/1.928/3.454/1.526 ms\n```\n\nFinally, run `tunio` with the `--proxy-addr` parameter pointing to Lantern and\nwith `--udpgw-remote-server-addr` pointing to `127.0.0.1:5353` (which is the\naddress of the udpgw server as the docker container sees it).\n\n```sh\n./tunio --tundev tun0 \\\n  --netif-ipaddr 10.0.0.2 \\\n  --netif-netmask 255.255.255.0 \\\n  --proxy-addr $PROXY_IP:2099 \\\n  --udpgw-remote-server-addr 127.0.0.1:5353\n```\n\nYou should be able to browse any site now, the request will be captured by tun0\nand it will be forwarded to tunio which is connected to Lantern using a\n`net.Dialer`.\n\n```\ncurl google.com\n# \u003cHTML\u003e\u003cHEAD\u003e\u003cmeta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"\u003e\n# \u003cTITLE\u003e302 Moved\u003c/TITLE\u003e\u003c/HEAD\u003e\u003cBODY\u003e\n# \u003cH1\u003e302 Moved\u003c/H1\u003e\n# The document has moved\n# \u003cA HREF=\"http://www.google.com.mx/?gfe_rd=cr\u0026amp;ei=lbvLVtb0FM_E8ge_zouwDg\"\u003ehere\u003c/A\u003e.\n# \u003c/BODY\u003e\u003c/HTML\u003e\n```\n\nHurray!\n\n[1]: https://github.com/ambrop72/badvpn/tree/master/tun2socks\n[2]: https://getlantern.org\n[3]: https://en.wikipedia.org/wiki/TUN/TAP\n[4]: https://felixc.at/BadVPN)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetlantern%2Ftunio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetlantern%2Ftunio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetlantern%2Ftunio/lists"}