Introduction
tun2socks
is used to "socksify" TCP (IPv4 and IPv6)
connections at the network layer. It implements a TUN virtual network
interface which accepts all incoming TCP connections (regardless of
destination IP), and forwards them through a SOCKS server. This allows
you to forward all connections through SOCKS, without
any need for application support. It can be used, for example, to
forward connections through a remote SSH server or through Tor. Because of how it works, it can even be installed on a Linux router to transparently forward clients through SOCKS.Installation
tun2socks
is part of BadVPN. If you're on Linux, just
build BadVPN with its CMake build system (or use the Gentoo package
net-misc/badvpn, the Arch AUR or Ubuntu PPA packages). You can build
just tun2socks without any other software in the package; this way, you
don't need to have the NSS and OpenSSL libraries installed:
mkdir badvpn-build
cd badvpn-build
cmake /path/to/badvpn -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1
make
Alternatively, you can use a shell script to compile
tun2socks
only, in case using CMake is a problem for you: http://badvpn.googlecode.com/svn/trunk/compile-tun2sock.sh .If you're on Windows, simply grab the Windows build of BadVPN.
Example (tunnelling through SSH)
First create a TUN device:- On Linux, use
ip tuntap add dev tun0 mode tun user
. - On Windows, install OpenVPN (or, if you already have it, click the start menu shortcut that creates a new TAP-Win32 device). The new device will appear in
Network Adapters
and will be identifiable by itsDevice Name
field (saying Tap-Win32 something).
Now start the program (on Linux, run it as
):
badvpn-tun2socks --tundev --netif-ipaddr 10.0.0.2
--netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:1080
where
is:- on Linux,
tun0
, - on Windows,
"tap0901:
(the three numbers are TUN interface IP address, network, and subnet mask).:10.0.0.1:10.0.0.0:255.255.255.0"
--netif-ipaddr 10.0.0.2
is not a typo. It
specifies the IP address of the virtual router inside the TUN device,
and must be different than the IP of the TUN interface itself.Now you should be able to ping the virtual router's IP (
10.0.0.2
).Connect to the SSH server, passing
-D localhost:1080
to the ssh
command to enable dynamic forwarding. This will make ssh
open a local SOCKS server which badvpn-tun2socks
will use.
If you use Putty, go to Connection->SSH->Tunnels, type 1080
in Source port
, choose Dynamic
and click Add
.All that remains is to route connections through the TUN device instead of the existing default gateway. This is done as follows:
- Add a route to the SSH server through your existing gateway, with a lower metric than the original default route.
- If your DNS servers are in the Internet (rather than your local
network), also add routes for them (like for the SSH server). This is
needed because
tun2socks
does not forward UDP by default (see below). - Add default route through the virtual router in the TUN device, with a lower metric than the original default route, but higher than the SSH and DNS routes.
For example (assuming there are no existing default routes with metric <=6; otherwise remove them or change their metrics), in Linux:
route add gw metric 5
route add default gw 10.0.0.2 metric 6
Or on Windows (NOTE:
tun2socks
must be running and the interface of the default gateway must be working for these to succeed):
route add metric 5
route add 0.0.0.0 mask 0.0.0.0 10.0.0.2 metric 6
These routes will not persist across a reboot. You should probably make scripts that install and remove them. You can remove a route by changing the
add
to del
or delete
, depending on whether you're in Linux or Windows.Windows 7: This OS has problems with respecting route metrics. If after a few minutes of normal operation connections suddenly stop being routed into tun2socks and instead go out the original default gateway, for no apparent reason, take a look at issue 5. One workaround is to temporarily remove the original default route.
UDP forwarding
tun2socks
can forward UDP, however this requires a daemon, badvpn-udpgw
to run on the remote SSH server. To enable UDP forwarding:- On the remote SSH server, start:
badvpn-udpgw --listen-addr 127.0.0.1:7300
- Add the following arguments to
badvpn-tun2socks
:--udpgw-remote-server-addr 127.0.0.1:7300
IPv6 support
NOTE: IPv6 support is only available in the SVN repository, and is not yet in a release version.IPv6 forwarding in tun2socks works much like IPv4 forwarding. It is enabled using the
--netif-ip6addr
command line option. For example, you can assign the address fdfe:dcba:9876::1
to the TUN interface, and tell tun2socks to assume the address fdfe:dcba:9876::2
, like this:
badvpn-tun2socks ...other..options... --netif-ip6addr fdfe:dcba:9876::2/126
Once this is done, you should be able to ping the virtual router inside tun2socks at
fdfe:dcba:9876::2
. To forward IPv6 through tun2socks, update your routing table appropriately.UDP forwarding via
badvpn-udpgw
also supports IPv6. It is irrelevant whether the connection to the badvpn-udpgw
program is made using IPv4 or IPv6, as long as it works.Using with Tor
The goal here is to have all connections initiating from a virtual machine go through Tor via tun2socks.NOTE: It is hard, but not impossible, to use tun2socks with Tor on a single host without a virtual machine, since the OS would have to route tun2socks outgoing connections differently from other programs. This can be achieved using policy routing, but this guide does not provide any more information.
WARNING: software in the VM may reveal information about you without your knowledge. The Tor project recommends only using the Tor Browser Bundle as your web browser. However, it is not possible to properly use this browser together with transparent proxying as described here. You should however at least use something like Chrome's Incognito mode; however, this is not equivalent to using the bundle. You can read more about the privacy features of the Tor Browser Bundle you may be missing on in this document.
NOTE: DNS queries done by the guest will be slower than if applications were directly configured to use Tor.
The following steps show how to set transparent proxying for the virtual machine.
- Let's assume you use VirtualBox to run the VM, and you run Tor on the host.
- Set the Network Adapter type in VirtualBox to Host Only.
- On the host, identify the IP address of the host on the VirtualBox interface. This IP address can found and configured in
File->Preferences->Network
. Most likely it will be192.168.56.1
. On a Linux host, this interface will likely be calledvboxnet0
. - On the host, configure Tor to provide a SOCKS and DNS server for the
VM to use. Do this by adding the following options to the torrc file
(use the right IP address): "
SocksListenAddress 192.168.56.1
" and "DNSPort 192.168.56.1:53
". - Start Tor on the host. If possible, verify that it's listening on port numbers
9050
and53
on the IP address of the VirtualBox interface (e.g. 192.168.56.1, not localhost!). On a Linux host, you can do this by runningnetstat -nlp
as root. - In the VM, configure the local network interface (the normal one, not TAP). Do not use DHCP; only set the IP address (e.g.
192.168.56.2
). At this point, is should be possible to ping the guest from the host, and the reverse. - On the guest, create and configure the TUN device for
tun2socks
, as is described in SSH tunneling example above. Additionally, set the default gateway (10.0.0.2
) as part of interface configuration, and use Tor's DNS server, e.g.192.168.56.1
. - Then finally start
tun2socks
in the guest, similarly to how it is done in the SSH example above. However, instead of using127.0.0.1:8080
as the SOCKS server, use Tor's SOCKS server running on the host, e.g.192.168.56.1:9050
. Note that you don't have to manually configure any routes; the default route on the TUN interface is all that is needed. This is because the SOCKS and DNS servers are on the local network, so you don't have to override the default tun2socks route.
This configuration has been tested using a Linux host and a Windows XP guest; however, it should work with any OS combination assuming the relevant software (tor, tun2socks) is supported. In particular, you're limited to Linux and Windows guests.
NOTE: Tor will issue warnings that IP addresses come without hostnames: "Warning: Your application (using socks5 to port 80) is giving Tor only an IP address....". This is normal and you might be able to silence it by adding these to torrc:
SafeSocks 0
TestSocks 0
WarnUnsafeSocks 0
from https://code.google.com/archive/p/badvpn/wikis/tun2socks.wiki
or:
https://github.com/ambrop72/badvpn/wiki/Tun2socks
------------------------------
mkdir badvpn-build
cd badvpn-build
wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/badvpn/badvpn-1.999.128.tar.bz2
tar xf badvpn-1.999.128.tar.bz2
cd bad*
cmake -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_UDPGW=1
make install
cd ..
rm -r bad*
cd ..
rm -r badvpn-build
echo "#!/bin/bash
badvpn-udpgw --listen-addr 127.0.0.1:7300 --max-clients 512 --max-connections-for-client 8" > /bin/badudp
chmod +x /bin/badudp
--------------------------
BadVPN详解之--编译与运行
从tun2socks一路撸下来,就是BadVPN了。
0.什么是BadVPN
BadVPN是另一种VPN框架,和OpenVPN平级等同,但是我个人认为它要比OpenVPN更加优秀。OpenVPN能实现的,BadVPN几乎都能实现,重要的是,BadVPN是一种更加优雅的Client2client的VPN实现。本文的目标是先让BadVPN跑起来,至于原理什么的,留到下一篇文章里细说。
1.阅读文档
和往常一样,我首先google关于BadVPN的一切,很遗憾,资源很有限,baidu的结果更是扯。所以和OpenVPN以及BBR一样,又让我树立了标杆,我决定自己来写。当然在写之前,我还是要把现有的资料先读完。首先我阅读了它的全部文档:https://code.google.com/archive/p/badvpn/wikis
从文档介绍中,我知道了BadVPN是一个控制与数据完全分离的VPN框架,这一点和OpenVPN完全不同,但这个并非本文的内容,而是下一篇文章的主题。本文是一个HowTo,旨在把BadVPN先跑起来。
2.下载源码
在资源有限的情况下,源码就是最好的资源,我当然会下载它,我用的是这个版本:https://github.com/ambrop72/badvpn当然,我下载源码的目的不是去阅读它,而是去运行它。我把源码解压后放在了/root/badvpn/目录下。
3.编译源码
在我的CentOS机器上,我首先安装了BadVPN所依赖的nss,nspr以及cmake:yum install nss-devel
yum install nspr-devel
yum install cmake
然后我开始编译BadVPN:
cmake /root/badvpn/badvpn-master -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1 -DBUILD_SERVER=1 -DBUILD_CLIENT=1
上面的cmake处理的含义是,编译tun2socks,badvpn-server,badvpn-client三个模块。
cd /root/badvpn/badvpn-master
make && make install
编译成功!
4.运行BadVPN
这里有详细的实例文档,我阅读并验证了它:https://code.google.com/archive/p/badvpn/wikis/Examples.wiki4.1.运行服务端
在设备1上运行:badvpn-server --listen-addr 0.0.0.0:7000 --loglevel 4 --logger stdout --ssl --nssdb sql:/home/vpnserver/nssdb --server-cert-name "vpnca"
以下是输出:
NOTICE(server): initializing BadVPN server 1.999.130
NOTICE(server): entering event loop
INFO(server): client 0 (192.168.44.131:55685): initialized
INFO(server): client 0 (192.168.44.131:55685) (peer-3): handshake complete
INFO(server): client 0 (192.168.44.131:55685) (peer-3): received hello
INFO(server): client 1 (192.168.44.129:40448): initialized
INFO(server): client 1 (192.168.44.129:40448) (peer-2): handshake complete
INFO(server): client 1 (192.168.44.129:40448) (peer-2): received hello
INFO(server): client 0 (192.168.44.131:55685) (peer-3): accepted 1
INFO(server): client 1 (192.168.44.129:40448) (peer-2): accepted 0
4.2.运行客户端
在设备2上运行:tunctl -u root -t tap0
ifconfig tap0 10.10.10.131/24 up
badvpn-client --server-addr 192.168.44.100:7000 --transport-mode udp --encryption-mode none --hash-mode none --scope local1 --bind-addr 0.0.0.0:8000 --num-ports 30 --ext-addr 1.1.1.131:8000 local1 --tapdev tap0 --loglevel 4 --server-name "vpnca" --ssl --nssdb sql:/home/vpnclient/nssdb --client-cert-name "peer-3" --encryption-mode blowfish --hash-mode md5 --otp blowfish 3000 2000
以下是输出:
NOTICE(client): initializing BadVPN client 1.999.130
INFO(client): device MTU is 1514
NOTICE(client): entering event loop
NOTICE(ServerConnection): connected
INFO(client): server: ready, my ID is 0
...
在设备3上运行:
tunctl -u root -t tap0
ifconfig tap0 10.10.10.129/24 up
badvpn-client --server-addr 192.168.44.100:7000 --transport-mode udp --encryption-mode none --hash-mode none --scope local1 --bind-addr 0.0.0.0:8000 --num-ports 30 --ext-addr 1.1.1.129:8000 local1 --tapdev tap0 --loglevel 4 --server-name "vpnca" --ssl --nssdb sql:/home/vpnclient/nssdb --client-cert-name "peer-2" --encryption-mode blowfish --hash-mode md5 --otp blowfish 3000 2000
以下是输出:
NOTICE(client): initializing BadVPN client 1.999.130
INFO(client): device MTU is 1514
NOTICE(client): entering event loop
NOTICE(ServerConnection): connected
INFO(client): server: ready, my ID is 1
INFO(client): peer 0 (peer-3): initialized; talking to peer in SSL server mode
NOTICE(client): peer 0 (peer-3): bound to address number 0
INFO(client): peer 0 (peer-3): up
运行成功,无错误输出。
5.玩法
此时在设备2上执行一个ping,即ping设备3的tap0的地址:ping 10.10.10.129
显然是通了!抓包,当然是密文。然而你知道以上的输出是什么意思吗?你觉得数据会经由什么路径到达目的地呢?你觉得加密的密钥是如何来的呢?
---------------
试用tun2socks
编译安装
1git clone https://github.com/ambrop72/badvpn.git
2cd badvpn
3mkdir badvpn-build
4cd badvpn-build
5cmake .. -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1
6make
添加tun0 启动 tun2soket
|
|
修改route;启动socks server
|
|
ss-local config sample
1{
2 "server":"remote_server",
3 "server_port":58888,
4 "local_port":1080,
5 "password":"pwd",
6 "timeout":60,
7 "method":"aes-256-cfb",
8 "fast-open": true,
9 "reuse_port": true,
10 "mode": "tcp_and_udp"
11}
dhcp route 误操作恢复
route del gw 失败后极容易引发route 表的混乱,使用dhclient
命令可以恢复
1[root@localhost ~]# route
2Kernel IP routing table
3Destination Gateway Genmask Flags Metric Ref Use Iface
4default localhost.local 0.0.0.0 UG 100 0 0 enp1s0
5192.168.0.0 0.0.0.0 255.255.0.0 U 100 0 0 enp1s0
6[root@localhost ~]# ip route show
7default via 192.168.0.159 dev enp1s0 proto static metric 100
8192.168.0.0/16 dev enp1s0 proto kernel scope link src 192.168.0.159 metric 100
9[root@localhost ~]# ip rule show
100: from all lookup local
1132765: from all fwmark 0x1 lookup 100
1232766: from all lookup main
1332767: from all lookup default
14
15[root@localhost ~]# dhclient
16
17[root@localhost ~]# ip route
18default via 192.168.1.1 dev enp1s0
19default via 192.168.0.159 dev enp1s0 proto static metric 100
20[root@localhost ~]# route
21Kernel IP routing table
22Destination Gateway Genmask Flags Metric Ref Use Iface
23default gateway 0.0.0.0 UG 0 0 0 enp1s0
24default localhost.local 0.0.0.0 UG 100 0 0 enp1s0
25192.168.0.0 0.0.0.0 255.255.0.0 U 100 0 0 enp1s0
curl -x socks5h://localhost:1080 http://www.google.com
for debug ss-local------------------------------
on linux desktop os,Turn SOCKS into VPN
安装相关软件
- badvpn
- shadowsocks-libev
- pdnsd
- dnsutils
$ pacman -S badvpn \
shadowsocks-libev \
pdnsd \
dnsutils
配置SOCKS代理
$ cat /etc/shadowsocks/jp.json
{
"server": "1.2.3.4",
"server_port": 8388,
"local_port": 1080,
"password": "******",
"timeout": 60,
"method": "aes-256-cfb"
}
$ systemctl start shadowsocks-libev@jp
$ curl -x socks5h://127.0.0.1:1080 ifconfig.co
45.32.57.113
配置本地网络
$ cat /etc/systemd/network/eth0.network
[Match]
Name=eth0
[Network]
DHCP=yes
DNS=127.0.0.1
[DHCP]
UseDNS=false
#[Route]
#Destination=45.32.57.113
#Gateway=192.168.31.1
DHCP暂不支持设置静态路由 (见#1850)
配置虚拟网络
$ cat /etc/systemd/network/tun0.netdev
[NetDev]
Name=tun0
Kind=tun
[Tunnel]
Remote=10.0.0.2
$ cat /etc/systemd/network/tun0.network
[Match]
Name=tun0
[Network]
Address=10.0.0.1/24
#[Route]
#Destination=0.0.0.0/1
#Gateway=10.0.0.2
#[Route]
#Destination=128.0.0.0/1
#Gateway=10.0.0.2
因为清理路由不方便, 所以转移到tun2socks.service
.
配置DNS服务
$ cat /etc/pdnsd.conf
global {
perm_cache = 10240;
cache_dir = /var/cache/pdnsd;
pid_file = /var/run/pdnsd.pid;
run_as= pdnsd;
server_ip = 0.0.0.0;
status_ctl = on;
query_method = tcp_only;
min_ttl = 15m;
max_ttl = 1w;
timeout = 10;
neg_domain_pol = auth;
}
server {
label = "opendns";
ip = 208.67.222.222, 208.67.220.220;
timeout = 4;
uptest = if;
interface = tun0;
interval = 15m;
proxy_only = on;
purge_cache = off;
preset = off;
}
source {
owner=localhost;
serve_aliases=on;
file="/etc/hosts";
}
rr {
name=localhost;
reverse=on;
a=127.0.0.1;
owner=localhost;
soa=localhost,root.localhost,42,86400,900,86400,86400;
}
neg {
name=baidu.com;
types=domain;
}
配置VPN服务
$ cat /etc/systemd/system/tun2socks.service
[Unit]
Description=BadVPN Tun2Socks Daemon
After=network.target
[Service]
ExecStartPre=/usr/bin/ip route add 45.32.57.113 via 192.168.31.1
ExecStartPre=/usr/bin/ip route add 0.0.0.0/1 via 10.0.0.2
ExecStartPre=/usr/bin/ip route add 128.0.0.0/1 via 10.0.0.2
ExecStart=/usr/bin/badvpn-tun2socks \
--tundev tun0 \
--netif-ipaddr 10.0.0.2 \
--netif-netmask 255.255.255.0 \
--socks-server-addr 127.0.0.1:1080
ExecStopPost=/usr/bin/ip route del 128.0.0.0/1 via 10.0.0.2
ExecStopPost=/usr/bin/ip route del 0.0.0.0/1 via 10.0.0.2
ExecStopPost=/usr/bin/ip route del 45.32.57.113 via 192.168.31.1
Restart=always
[Install]
WantedBy=multi-user.target
$ systemctl daemon-reload
大功告成
$ systemctl restart systemd-networkd
$ systemctl start pdnsd
$ systemctl start tun2socks
$ curl ifconfig.co
45.32.57.113
tun2socks-manager
Manage automatically SOCKS5 tunnel created with tun2socks from package badvpn.
Install client
Install dependencies:
sudo apt install dnsmasq-base
We need badvpn-tun2socks:
sudo apt install cmake
git clone https://github.com/ambrop72/badvpn.git
cd badvpn
mkdir badvpn-build
cd badvpn-build
cmake .. -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1
make
sudo cp tun2socks/badvpn-tun2socks /usr/local/bin
Install tun2socks-manager:
cd tun2socks-manager
sudo make install
Install server
By default tun2socks is configured to use UDP forwarding (parameter TUN2SOCKS_UDPGW_REMOTE
) for better performance. This requires running badvpn-udpgw
on the server side (as standard user, no root access mandatory). For instance:
git clone https://github.com/ambrop72/badvpn.git
cd badvpn
mkdir badvpn-build
cd badvpn-build
cmake .. -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_UDPGW=1
make
sudo cp badvpn-udpgw /usr/local/bin # if no root: install in ~/bin
Then we need to run it automatically. Using systemd, we first create a service file /etc/systemd/system/udpgw.service
containing:
[Unit]
Description=UDP forwarding for badvpn-tun2socks
After=nss-lookup.target
[Service]
ExecStart=/usr/local/bin/badvpn-udpgw --loglevel none --listen-addr 127.0.0.1:7300
User=udpgw
[Install]
WantedBy=multi-user.target
Then we create the user, and enable / start the service:
sudo useradd -m udpgw
sudo systemctl enable udpgw
sudo systemctl start udpgw
An non-root alternative is to edit the crontab (crontab -e
) and add a user @reboot
event:
@reboot sleep 15 && ~/bin/badvpn-udpgw --loglevel none --listen-addr 127.0.0.1:7300
Configure
See file /etc/tun2socks-manager.conf
and per-connection sample file in /etc/tun2socks-manager.d
.
Troubleshooting
Error org.freedesktop.DBus.Error.ServiceUnknown with dnsmasq
Error org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.NetworkManager.dnsmasq
was not provided by any .service files
Debugging
Messages are sent to /var/log/messages
:
grep tun2socks-manager /var/log/messages
When troubleshooting, it helps to follow these messages in a separate window. For instance:
tail -f /var/log/messages
tun2socks-manager
is installed as a Network Manager (NM) dispatcher script. When NM starts, it launches the tun2socks-manager with:
/usr/local/bin/tun2socks-manager start
Then, NM sends up
or down
event to the script, which updates the routing table based on configuration files in /etc/tun2socks-manager.d/
. This can be triggered manually with:
/usr/local/bin/tun2socks-manager update eth0 up # Simulate up event on itf eth0
from https://github.com/xeyownt/tun2socks-manager
No comments:
Post a Comment