Building a SOCKS router on a laptop with Debian 10

For a whole year (or two), I postponed publishing this article for a main reason β€” I had already published two articles where I described the process of creating a SOCKS router from a regular laptop running Debian.

However, since then, the stable version of Debian has been updated to Buster, and I received enough messages asking for help with the configuration, which means my previous articles are not exhaustive. Well, I suspected that the methods outlined in them do not fully cover all the intricacies of configuring Linux for routing in SOCKS. Moreover, they were written for Debian Stretch, and after upgrading to Buster, in the systemd initialization system, I noticed subtle changes in the interaction of services. Additionally, I did not use systemd-networkd in the articles, even though it is best suited for complex network configurations.

In addition to the aforementioned changes, my configuration has included services such as hostapd β€” a service for virtual access point creation, ntp for synchronizing time for local network clients, dnscrypt-proxy for encrypting connections via the DNS protocol and disabling ads on local network clients, and as I mentioned earlier, systemd-networkd for configuring network interfaces.

Here’s a simple block diagram of the internal structure of such a router.

Building a SOCKS router on a laptop with Debian 10

So, let me remind you what the goals of this series of articles are:

  1. To route all OS connections through SOCKS, as well as connections from all devices on the same network as the laptop.
  2. In my case, the laptop must remain fully mobile. That is, it should allow the use of a desktop environment and not be tied to a physical location.
  3. The last point implies connecting and routing solely through the built-in wireless interface.
  4. And, of course, to create a comprehensive guide, as well as to discuss the relevant technologies to the best of my modest knowledge.

What will be covered in this article:

  1. git β€” we will download the project repositories tun2socks, necessary for routing TCP traffic to SOCKS, and create_ap β€” a script for automating the configuration of a virtual access point using hostapd.
  2. tun2socks β€” we will build and install the systemd service.
  3. systemd-networkd β€” we will configure wireless and virtual interfaces, static routing tables, and packet forwarding.
  4. create_ap β€” we will set up the systemd service, configure it, and launch a virtual access point.

Optional steps:

  • ntp β€” we will set up and configure a server for time synchronization on the clients of the virtual access point.
  • dnscrypt-proxy β€” we will encrypt DNS requests, route them through SOCKS, and disable advertising domains for the local network.

Why all this?

This is one way to organize protection for TCP connections in a local network. The main advantage is that all connections go through SOCKS unless a static route is set through the original gateway. This means you don't need to configure the SOCKS server settings for individual programs or clients in the local network β€” they all go through SOCKS by default, as it is the default gateway until we specify otherwise.

Essentially, we add a second encrypting router as a laptop in front of the original router and use the original router's internet connection for the already encrypted SOCKS requests from the laptop, which, in turn, routes and encrypts the requests from the local network clients.

From the provider's perspective, we are constantly connected to a single server with encrypted traffic.

Accordingly, all devices connect to the virtual access point of the laptop.

Install tun2socks on the system

As long as your machine has internet access, download all necessary tools.

apt update
apt install git make cmake

Download the badvpn package

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

A folder named badvpn will appear in your system.Create a separate folder for the build

mkdir badvpn-build

Go into it

cd badvpn-build

Build it tun2socks

cmake ../badvpn -DBUILD_NOTHING_BY_DEFAULT=1 -DBUILD_TUN2SOCKS=1

Install it on the system,

make install
  • Parameter -DBUILD_NOTHING_BY_DEFAULT=1 disables building all components of the badvpn repository.
  • β€”DBUILD_TUN2SOCKS=1 enables building the component tun2socks.
  • make install β€” will install the tun2socks binary in your system at /usr/local/bin/badvpn-tun2socks.

Set up the tun2socks service in systemd

Create a file /etc/systemd/system/tun2socks.service with the following content:

[Unit]
Description=SOCKS TCP Relay

[Service]
ExecStart=/usr/local/bin/badvpn-tun2socks --tundev tun2socks --netif-ipaddr 172.16.1.1 --netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:9050

[Install]
WantedBy=multi-user.target
  • --tundev β€” takes the name of the virtual interface that we initialize using systemd-networkd.
  • --netif-ipaddr β€” the network address of the 'router' tun2socks to which the virtual interface connects. It is better to make it a separate reserved subnet..
  • --socks-server-addr β€” takes the socket (address:port of the SOCKS server).

If your SOCKS server requires authentication, you can specify the parameters. --username and --password.

Next, register the service

systemctl daemon-reload

And enable

systemctl enable tun2socks

Before starting the service, we'll provide it with a virtual network interface.

Let's switch to systemd-networkd

We enable systemd-networkd:

systemctl enable systemd-networkd

Disable current network services.

systemctl disable networking NetworkManager NetworkManager-wait-online
  • NetworkManager-wait-online β€” this is a service that waits for a working network connection before systemd continues to start other services that depend on the network. We disable it as we will switch to the systemd-networkd equivalent.

Let's enable it right away:

systemctl enable systemd-networkd-wait-online

Configure the wireless network interface

Create a systemd-networkd configuration file for the wireless network interface /etc/systemd/network/25-wlp6s0.network.

[Match]
Name=wlp6s0

[Network]
Address=192.168.1.2/24
IPForward=yes
  • Name β€” this is the name of your wireless interface. Identify it with the command ip a.
  • IPForward β€” this directive enables packet forwarding on the network interface.
  • Address is responsible for assigning an IP address to the wireless interface. We specify it statically because with the equivalent directive DHCP=yes, systemd-networkd would create a default gateway in the system. Then all traffic would go through the original gateway instead of the future virtual interface in a different subnet. You can check the current default gateway with the command ip r

Create a static route for the remote SOCKS server

If your SOCKS server is not local, but remote, you need to create a static route for it. To do this, add a section Route at the end of the configuration file you created for the wireless interface with the following content:

[Route]
Gateway=192.168.1.1
Destination=0.0.0.0
  • Gateway β€” this is the default gateway or the address of your original access point.
  • Destination β€” this is the address of your SOCKS server.

Configure wpa_supplicant for systemd-networkd

systemd-networkd uses wpa_supplicant to connect to a secure access point. When trying to 'bring up' the wireless interface, systemd-networkd starts the service wpa_supplicant@name, where name β€” this is the name of the wireless interface. If you haven't used systemd-networkd up to this point, this service is likely absent on your system.

Therefore, create it with the command:

systemctl enable wpa_supplicant@wlp6s0

I used wlp6s0 as the name of your wireless interface. This name might be different for you. You can find it out with the command ip l.

Now the created service wpa_supplicant@wlp6s0 will start when the wireless interface is "brought up," but it will, in turn, look for the SSID settings and access point password in the file /etc/wpa_supplicant/wpa_supplicant-wlp6s0. Therefore, it is necessary to create it using the utility wpa_passphrase.

To do this, execute the command:

wpa_passphrase SSID password>/etc/wpa_supplicant/wpa_supplicant-wlp6s0.conf

where SSID β€” is the name of your access point, password β€” is the password, and wlp6s0 β€” is the name of your wireless interface.

Initialize the virtual interface for tun2socks

Create a file for initializing the new virtual interface in the system/etc/systemd/network/25-tun2socks.netdev

[NetDev]
Name=tun2socks
Kind=tun
  • Name β€” is the name that systemd-networkd will assign to the future virtual interface upon initialization.
  • Kind β€” is the type of the virtual interface. From the service name tun2socks, you can guess that it uses a type of interface tun.
  • netdev β€” is an extension of the files that systemd-networkd are used to initialize virtual network interfaces. The address and other network settings for these interfaces are specified in .network-files.

Create such a file /etc/systemd/network/25-tun2socks.network with the following content:

[Match]
Name=tun2socks

[Network]
Address=172.16.1.2/24
Gateway=172.16.1.1
  • Name β€” the name of the virtual interface that you specified in netdev-file.
  • Address β€” the IP address that will be assigned to the virtual interface. It must be on the same network as the address you specified in the tun2socks service
  • Gateway β€” the IP address of the "router" tun2socks, which you specified when creating the systemd service.

Thus, the interface tun2socks has the address 172.16.1.2, while the service tun2socks β€” 172.16.1.1, meaning it acts as a gateway for all connections from the virtual interface.

Configure the virtual access point

Install dependencies:

apt install util-linux procps hostapd iw haveged

Download the repository create_ap to your machine:

git clone https://github.com/oblique/create_ap

Change to the repository folder on your machine:

cd create_ap

Install it on the system:

make install

Your system will have the config /etc/create_ap.conf. Here are the main options to edit:

  • GATEWAY=10.0.0.1 β€” it is better to create a separate reserved subnet.
  • NO_DNS=1 β€” disable it, as this parameter will be managed by the systemd-networkd virtual interface.
  • NO_DNSMASQ=1 β€” disable it for the same reason.
  • WIFI_IFACE=wlp6s0 β€” the wireless interface of the laptop.
  • INTERNET_IFACE=tun2socks β€” the virtual interface created for tun2socks.
  • SSID=hostapd β€” the name of the virtual access point.
  • PASSPHRASE=12345678 β€” the password.

Don't forget to enable the service:

systemctl enable create_ap

Enable the DHCP server in systemd-networkd

The service create_ap initializes the virtual interface ap0The idea is that dnsmasq is 'hanging' on this interface, but why install unnecessary services when systemd-networkd has a built-in DHCP server?

To enable it, we will define the network settings for the virtual point. For this, create a file /etc/systemd/network/25-ap0.network with the following content:

[Match]
Name=ap0

[Network]
Address=10.0.0.1/24
DHCPServer=yes

[DHCPServer]
EmitDNS=yes
DNS=10.0.0.1
EmitNTP=yes
NTP=10.0.0.1

After the create_ap service initializes the virtual interface ap0, systemd-networkd will automatically assign it an IP address and enable the DHCP server.

The lines EmitDNS=yes and DNS=10.0.0.1 pass the DNS server settings to devices connected to the access point.

If you do not plan to use a local DNS server β€” in my case it's dnscrypt-proxy β€” you can set DNS=10.0.0.1 downward API support (simultaneously with this in DNS=192.168.1.1, where 192.168.1.1 β€” the address of your original gateway. Then the DNS queries from your host and local network will go unencrypted through your provider's servers.

EmitNTP=yes and NTP=192.168.1.1 pass the NTP settings.

The same goes for the line NTP=10.0.0.1.

Install and configure the NTP server

Install it on the system:

apt install ntp

Edit the config /etc/ntp.conf. Comment out the addresses of the standard pools:

#pool 0.debian.pool.ntp.org iburst
#pool 1.debian.pool.ntp.org iburst
#pool 2.debian.pool.ntp.org iburst
#pool 3.debian.pool.ntp.org iburst

Add the addresses of public servers, for example, Google Public NTP:

server time1.google.com iburst
server time2.google.com iburst
server time3.google.com iburst
server time4.google.com iburst

Provide access to the server for clients in your network:

restrict 10.0.0.0 mask 255.255.255.0

Enable broadcasting in your network:

broadcast 10.0.0.255

Finally, add the addresses of these servers to the static routing table. For this, open the wireless interface configuration file /etc/systemd/network/25-wlp6s0.network and add to the end of the section Route.

[Route]
Gateway=192.168.1.1
Destination=216.239.35.0

[Route]
Gateway=192.168.1.1
Destination=216.239.35.4

[Route]
Gateway=192.168.1.1
Destination=216.239.35.8

[Route]
Gateway=192.168.1.1
Destination=216.239.35.12

You can find out the addresses of your NTP servers using the utility host as follows:

host time1.google.com

Install dnscrypt-proxy, remove ads and hide DNS traffic from your provider

apt install dnscrypt-proxy

To serve the DNS queries of the host and local network, edit the socket /lib/systemd/system/dnscrypt-proxy.socket. Change the following lines:

ListenStream=0.0.0.0:53
ListenDatagram=0.0.0.0:53

Restart systemd:

systemctl daemon-reload

Edit the config /etc/dnscrypt-proxy/dnscrypt-proxy.toml:

server_names = ['adguard-dns']

To route connections through dnscrypt-proxy via tun2socks, add below:

force_tcp = true

Edit the config /etc/resolv.conf, which informs the DNS server about the host.

nameserver 127.0.0.1
nameserver 192.168.1.1

The first line enables the use of dnscrypt-proxy, while the second uses the original gateway, in case the dnscrypt-proxy server is unavailable.

Done!

Reboot or stop the active network services:

systemctl stop networking NetworkManager NetworkManager-wait-online

And restart all necessary ones:

systemctl restart systemd-networkd tun2socks create_ap dnscrypt-proxy ntp

After rebooting or restarting, you will have a second access point that routes the host and local network devices to SOCKS.

This is what the output looks like ip a of a regular laptop:

1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: tun2socks:  mtu 1500 qdisc pfifo_fast state UP group default qlen 500
    link/none 
    inet 172.16.1.2/24 brd 172.16.1.255 scope global tun2socks
       valid_lft forever preferred_lft forever
    inet6 fe80::122b:260:6590:1b0e/64 scope link stable-privacy 
       valid_lft forever preferred_lft forever
3: enp4s0:  mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether e8:11:32:0e:01:50 brd ff:ff:ff:ff:ff:ff
4: wlp6s0:  mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 4c:ed:de:cb:cf:85 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 brd 192.168.1.255 scope global wlp6s0
       valid_lft forever preferred_lft forever
    inet6 fe80::4eed:deff:fecb:cf85/64 scope link 
       valid_lft forever preferred_lft forever
5: ap0:  mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 4c:ed:de:cb:cf:86 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 brd 10.0.0.255 scope global ap0
       valid_lft forever preferred_lft forever
    inet6 fe80::4eed:deff:fecb:cf86/64 scope link 
       valid_lft forever preferred_lft forever

As a result,

  1. The provider only sees the encrypted connection to your SOCKS server, meaning they cannot see anything.
  2. However, they can see your NTP requests. To prevent this, remove static routes for the NTP servers. However, it is not guaranteed that your SOCKS server allows the NTP protocol.

A workaround noted on Debian 10

If you try to restart the network service from the console, it will crash with an error. This is because its part in the form of a virtual interface is bound to the tun2socks service, meaning it is in use. To restart the network service, you first need to stop the tun2socks service. But, I think, if you read this far, this is definitely not a problem for you!

Links

  1. Static routing in Linux β€” IBM
  2. systemd-networkd.service β€” Freedesktop.org
  3. Tun2socks Β· ambrop72/badvpn Wiki Β· GitHub
  4. oblique/create_ap: This script creates a NATed or Bridged WiFi Access Point.
  5. dnscrypt-proxy 2 β€” A flexible DNS proxy, with support for encrypted DNS protocols.

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers πŸ”₯ Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster