About

Given a SOCKS proxy (such as tor), the goal is to selectively route packets through the SOCKS proxy by using iptables packet marking and mangling. The problem is that a SOCKS proxy operates at the OSI session layer 5 whilst iptables mainly operates on lower layers such as OSI layer 3 (for IP addresses) or 4 for ports - in other words, to bridge the gap, one would need some TCP/IP application layer software that will accept packets and push them through the SOCKS proxy.

Requirements

  • badvpn - either compiled from source or installed as a distribution package,
  • iproute2 - usually part of any modern distro; to check make sure that the command ip is available,
  • an upstream SOCKS proxy to push packets through such as Tor.

Downloads

Compiling tun2socks

badvpn is needed, either as a distribution package or compiled manually. This step can be skipped if the distribution provides binaries.

To compile manually on distributions that do not bundle badvpn, clone the repository:

git clone https://github.com/ambrop72/badvpn.git

and then compile the source by issuing:

cd badvpn
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1
make

and copy the badvpn-tun2socks into /usr/local/sbin. The compilation may require libnss3-dev and libnspr4-dev to be installed in order to succeed.

Setting up the Service File

Next, copy the following contents into a file at /etc/systemd/system/tun2socks-tor1.service:

tun2socks-tor1.service
[Unit]
Description = Tun2Socks for Tor1
After = network.target
 
[Service]
# Configuration
Environment=TUN_IF_NAME=tor1
Environment=TUN_IF_NETWORK=169.254.1.1/30
Environment=FW_MARK=0x32
Environment=RT_TABLE=tor1
Environment=TUN_IF_GATEWAY=169.254.1.2
Environment=TUN_IF_NETMASK=255.255.255.252
Environment=SOCKS_SERVER=127.0.0.1:9051
# Service settings
Restart=always
PIDFile = /var/run/tun2socks-tor1.pid
User=root
Group=root
# Pre start (brings interfaces up and establishes routes).
ExecStartPre = -/sbin/ip tuntap add dev ${TUN_IF_NAME} mode tun
ExecStartPre = -/sbin/ip link set ${TUN_IF_NAME} up
ExecStartPre = -/sbin/ip addr add ${TUN_IF_NETWORK} dev ${TUN_IF_NAME}
ExecStartPre = -/sbin/ip rule add fwmark ${FW_MARK} lookup ${RT_TABLE}
ExecStartPre = -/sbin/ip route add default via ${TUN_IF_GATEWAY} table ${RT_TABLE}
# Start (starts tun2socks)
ExecStart = /usr/local/sbin/badvpn-tun2socks --logger syslog --loglevel info --tundev ${TUN_IF_NAME} --netif-ipaddr ${TUN_IF_GATEWAY} --netif-netmask ${TUN_IF_NETMASK} --socks-server-addr ${SOCKS_SERVER}
# Post stop (removes established routes and brings down interfaces).
ExecStopPost = -/sbin/ip route del default via ${TUN_IF_GATEWAY} table ${RT_TABLE}
ExecStopPost = -/sbin/ip rule del table ${RT_TABLE}
ExecStopPost = -/sbin/ip addr del ${TUN_IF_NETWORK} dev ${TUN_IF_NAME}
ExecStopPost = -/sbin/ip link set ${TUN_IF_NAME} down
ExecStopPost = -/sbin/ip tuntap del dev ${TUN_IF_NAME} mode tun
 
[Install]
WantedBy = multi-user.target

and proceed to configure the file.

Configuration

If you look at the newly created file at /etc/systemd/system/tun2socks-tor1.service it contains the following section preceded by a Configuration comment:

Environment=TUN_IF_NAME=tor1
Environment=TUN_IF_NETWORK=169.254.1.1/30
Environment=FW_MARK=0x32
Environment=RT_TABLE=tor1
Environment=TUN_IF_GATEWAY=169.254.1.2
Environment=TUN_IF_NETMASK=255.255.255.252
Environment=SOCKS_SERVER=127.0.0.1:9051

where:

  • TUN_IF_NAME is the name of a virtual network interface that will be used to route packets through the SOCKS proxy,
  • TUN_IF_NETWORK is a network for the virtual network interface consisting in an IP address for the interface 169.254.1.1 and a netmask 30,
  • FW_MARK is the packet marking that will be routed through the SOCKS proxy - in this case, in hex 0x32 is equivalent to 50 decimal,
  • RT_TABLE is the name of an iproute2 table defined usually in the file /etc/iproute2/rt_tables.
  • TUN_IF_GATEWAY is the gateway of the virtual network interface,
  • 255.255.255.252 is the netmask of the virtual network interface and,
  • 127.0.0.1:9051 is the IP address and port where a SOCKS proxy will be listening

With the configuration explained, the file /etc/iproute2/rt_tables has to be modified in order to define a routing table. Following the example, a new line would be added reading:

50    tor1

where:

  • 50 is an identifying ID number (the same as the decimal value of FW_MARK for simplicity's sake),
  • tor1 is the name of the table and corresponds to the RT_TABLE setting.

Similarly, a SOCKS proxy such as Tor can be setup to listen on the IP address 127.0.0.1 and port 9051 by editing the Tor configuration file commonly found at /etc/tor/torrc:

SocksPort 127.0.0.1:9051

Now, with the table defined and the file /etc/systemd/system/tun2socks-tor1.service edited to adjust the configuration, the following commands can be used to start tun2socks:

systemctl enable tun2socks-tor1.service
systemctl start tun2socks-tor1

if all goes well, no output shall be returned - otherwise, systemctl and journalctl can be used to debug why the service has not started.

Testing

Following the example, one can check whether the TUN interface has been brought up by issuing:

ifconfig tor1

which should output something similar to:

tor1: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 169.254.1.1  netmask 255.255.255.252  destination 169.254.1.1
        inet6 fe80::47a6:fb65:d814:aa06  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 0  bytes 0 (0.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Next, to check that the routes have been applied properly, issue:

ip rule show

which should show an output similar to:

145:	from all fwmark 0x32 lookup tor1

This says that all packets marked with the identifier 0x32 (or 50 in decimal) shall look up the table tor1 for routing decisions.

Now, to check that the table tor1 contains the desired routing decisions, issue:

ip route show table tor1

which should output something similar to:

default via 169.254.1.2 dev tor1

The systemd service file, performs the following operations in order:

  1. create a TUN interface named tor1,
  2. bring the TUN interface up,
  3. assign the IP and netmask address 169.254.1.1/30 to the TUN interface,
  4. add a rule that will make packets marked with the identifier 0x32 lookup a table named tor1,
  5. add the default route via 169.254.1.2 and the device tor1 to the table tor1.

such that it is easy to check, given a potential failure, which command failed in the process of starting up the service.

Mangling Packets

Now, we can play around with packets, for instance, we can route all outbound SSH connections through the SOCKS proxy:

iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 0x32

Or even route entire subnet traffic through the SOCKS proxy:

iptables -t mangle -A PREROUTING -s 192.168.2.0/24 -j MARK --set-mark 0x32

and so on and so forth.

The Squid Connection

The Squid proxy has a very interesting feature that allows traffic through the proxy to be marked depending on ACLs defined in the configuration.

For instance, using Squid, an ACL can be defined that matches the destination domain google.com:

acl google dstdom google.com

Now, given the google ACL, Squid can be told to mark all packets matching the ACL with an identifier, for instance, by adding the line:

tcp_outgoing_mark 0x32 google

Whenever a client behind the Squid proxy browses to google.com, all packets will be marked with the identifier 0x32 and they will then be, in turn, routed to the virtual network device tor1 where tun2socks will pick up the connection and route it through the Tor SOCKS proxy listening on the IP 127.0.0.1 and port 9051.

In essence, this method would allow passing requests from clients behind a Squid proxy to Tor without using an upstream helper proxy such as polipo or privoxy.

Squid SSL Intercept

If Squid is configured to do SSL interception, then all bumped domains would have to be fetched directly, thereby loosing the ability to route the data through the Tor network. By using this setup, all direct requests made my Squid will fetch all resources through the Tor network and retain the privacy properties.


networking/routing_packets_through_socks_proxies_via_packet_mangling.txt · Last modified: 2022/04/30 12:22 by office

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.