Building a router in SOCKS on a laptop with Debian 10

For a whole year (or two) I postponed the publication of this article for the main reason - I have already published two articles in which I described the process of creating a router in SOCKS from a regular laptop with Debian.

However, since then the stable version of Debian has been updated to Buster, a sufficient number of people have sent me a personal request to help with the configuration, which means that my previous articles are not exhaustive. Well, I myself guessed that the methods described in them did not fully reveal all the intricacies of configuring Linux for routing in SOSKS. In addition, they were written for Debian Stretch, and after upgrading to Buster, in the systemd initialization system, I noticed small changes in the interaction of services. Yes, and in the articles themselves, I did not use systemd-networkd, although it is best suited for complex network configurations.

In addition to the above changes, services like hostapd were added to my configuration - a service for access point virtualization, ntp for synchronizing the time of local network clients, dnscrypt-proxy for encrypting DNS connections and disabling advertising on local network clients, as well as, as I mentioned previously, systemd-networkd for configuring network interfaces.

Here is the simplest block diagram of the internal structure of such a router.



So, I remind you what the objectives of the cycle of these articles are:

  1. Route all OS connections to SOCKS, as well as the connections of all devices that are on the same network as the laptop.
  2. The laptop in my case should remain fully mobile. That is, to give the opportunity to use the desktop environment and not be tied to a physical location.
  3. The last point involves connecting and routing only through the built-in wireless interface.
  4. Well, of course, the creation of an exhaustive guide, as well as the analysis of appropriate technologies to the best of my modest knowledge.

What will be considered in this article:

  1. git - download the tun2socks project repositories needed to route TCP traffic to SOCKS, and create_ap - a script to automate the configuration of a virtual access point using hostapd .
  2. tun2socks - build and install the systemd service on the system .
  3. systemd-networkd - configure wireless and virtual interfaces, static routing tables, and packet forwarding.
  4. create_ap - install the systemd service on the system, configure and launch the virtual access point.

Optional steps:

  • ntp - install and configure the server to synchronize time on the clients of the virtual access point.
  • dnscrypt-proxy - encrypt DNS queries, route them to SOCKS and disable advertising domains for the local network.

Why all this?


This is one way of securing TCP connections on a local network. The main advantage is that all connections go to SOCKS if a static route through the original gateway is not built for them. This means that it is not necessary to prescribe the settings of the SOCKS server to either individual programs or clients on the local network - they all go to SOCKS by default, since it is the default gateway until we specify the opposite.

In fact, we add the second encryption router as a laptop in front of the original router and use the Internet connection of the original router for the already encrypted SOCKS requests of the laptop, which, in turn, routes and encrypts the requests of the local network clients.

From the point of view of the provider, we are constantly connected to the same server with encrypted traffic.

Accordingly, all devices connect to a laptop’s virtual access point.

Before you start


Almost all configs are available in the repository .

Install tun2socks into the system


As long as you have internet on your machine, download all the necessary tools.

apt update

apt install git make cmake

Download the badvpn package
git clone https://github.com/ambrop72/badvpn

The badvpn folder will appear on your system . Create a separate build folder

mkdir badvpn-build

Go to her

cd badvpn-build

Build tun2socks

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

Install to system

make install

  • The -DBUILD_NOTHING_BY_DEFAULT = 1 parameter disables the assembly of all components of the badvpn repository .
  • DBUILD_TUN2SOCKS = 1 includes tun2socks components in the assembly .
  • make install - installs the tun2socks binary on your system at / usr / local / bin / badvpn-tun2socks.

Install tun2socks service in systemd


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

[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 - accepts the name of the virtual interface that we initialize with systemd-networkd .
  • --netif-ipaddr - network address of the “router” tun2socks to which the virtual interface is connected. It is better to make a separate reserved subnet .
  • --socks-server-addr - accepts a socket ( address: SOCKS server port ).

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

Next, register the service

systemctl daemon-reload

And turn on

systemctl enable tun2socks

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

Go to systemd-networkd


Turn on systemd-networkd :

systemctl enable systemd-networkd

Disable current network services.

systemctl disable networking NetworkManager NetworkManager-wait-online

  • NetworkManager-wait-online is a service that waits for a working network connection before systemd continues to start other services depending on the availability of the network. We disable it, as we switch to the analog systemd-networkd .

Let's turn it on right away:

systemctl enable systemd-networkd-wait-online

Set up a 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
IPMasquerade=yes

  • Name is the name of your wireless interface. Identify it with the ip a command .
  • IPMasquerade is a directive that includes masquerading and packet forwarding on a 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 creates a default gateway in the system. Then all traffic will go through the original gateway, and not through the future virtual interface in an excellent 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, then you need to create a static route for it. To do this, add the Route section at the end of the wireless configuration file you created with the following contents:

[Route]
Gateway=192.168.1.1
Destination=0.0.0.0

  • Gateway is the default gateway or address of your original access point.
  • Destination - SOCKS server address.

Configure wpa_supplicant for systemd-networkd


systemd-networkd uses wpa_supplicant to connect to a secure access point. When you try to "raise" the wireless interface, systemd-networkd starts the service wpa_supplicant @ name , where name is the name of the wireless interface. If you have not used systemd-networkd before this point, then for certain this service is not available on your system.

Therefore, create it with the command:

systemctl enable wpa_supplicant@wlp6s0

I used wlp6s0 as the name of my wireless interface. Your name may be different. You can find out by his team
ip l
.

Now the created wpa_supplicant @ wlp6s0 service will start when the wireless interface is “lifted”, however, it, in turn, will look for the SSID and password of the access point in the file / etc / wpa_supplicant / wpa_supplicant-wlp6s0 . Therefore, you must create it using the wpa_passphrase utility .

To do this, run 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 virtual interface for tun2socks


Create a file to initialize a 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 when it is initialized.
  • Kind is a type of virtual interface. Based on the name of the tun2socks service , you can guess that it uses an interface like tun .
  • netdev is the file extension that systemd-networkd uses to initialize virtual network interfaces. The address and other network settings for these interfaces are specified in .network files.

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

[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 the netdev file.
  • Address - IP address to be assigned to the virtual interface. Must be on the same network as the address you specified in tun2socks
  • Gateway - the IP address of the “router” tun2socks that you specified when creating the systemd service .

Thus, the tun2socks interface has the address 172.16.1.2 , and the tun2socks service is 172.16.1.1 , that is, it is the gateway for all connections from the virtual interface.

Configure a virtual access point


Install the dependencies:

apt install util-linux procps hostapd iw haveged

Download the create_ap repository to your machine:

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

Go to the repository folder on your machine:

cd create_ap

Install in the system:

make install

The config /etc/create_ap.conf will appear on your system . Here are the main options for editing:

  • GATEWAY = 10.0.0.1 - it is better to make a separate reserved subnet.
  • NO_DNS = 1 - turn off, since this parameter will be controlled by the virtual systemd-networkd interface.
  • NO_DNSMASQ = 1 - turn off for the same reason.
  • WIFI_IFACE = wlp6s0 - wireless interface of the laptop.
  • INTERNET_IFACE = tun2socks> - virtual interface created for tun2socks .
  • SSID = hostapd - name of the virtual access point.
  • PASSPHRASE = 12345678 - password.

Remember to enable the service:

systemctl enable create_ap

Enable DHCP server in systemd-networkd


The create_ap service initializes the ap0 virtual interface on the system . Theoretically , dnsmasq hangs on this interface , but why install extra services if systemd-networkd contains a built-in DHCP server?

To enable it, define the network settings for the virtual point. To do this, create the file /etc/systemd/network/25-ap0.network with the following contents:

[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 service sreate_ap initializes virtual interface Ap0 , systemd-NetworkD automatically assign 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 is dnscrypt-proxy - you can set DNS = 10.0.0.1 to DNS = 192.168.1.1 , where 192.168.1.1 is the address of your original gateway. Then the DNS queries of your host and local network will go unencrypted through the provider's servers.

EmitNTP = yesand NTP = 192.168.1.1 transmit the NTP settings.

The same goes for the line NTP = 10.0.0.1 .

Install and configure NTP server


Install in the system:

apt install ntp

Edit the config /etc/ntp.conf . Comment out the addresses of 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 ibrust
server time2.google.com ibrust
server time3.google.com ibrust
server time4.google.com ibrust

Grant access to the server to clients from your network:

restrict 10.0.0.0 mask 255.255.255.0

Turn the broadcast into your network:

broadcast 10.0.0.255

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

[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 host utility as follows:

host time1.google.com

Install dnscrypt-proxy , remove ads and hide DNS traffic from the 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 dnscrypt-proxy connections through tun2socks , add below:

force_tcp = true

Edit the /etc/resolv.conf config that tells the DNS server to the host.

nameserver 127.0.0.1
nameserver 192.168.1.1

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

Done!


Reboot or stop existing network services:

systemctl stop networking NetworkManager NetworkManager-wait-online

And restart all the 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 LAN devices to SOCKS.

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

1: lo: <LOOPBACK,UP,LOWER_UP> 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: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> 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: <NO-CARRIER,BROADCAST,MULTICAST,UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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

Eventually


  1. The provider only sees the encrypted connection to your SOCKS server, which means that it does not see anything.
  2. And yet he sees your NTP requests, to prevent this, delete the static routes for NTP servers. However, it is not a fact that your SOCKS server allows NTP.

Crutch seen on Debain 10


If you try to restart the network service from the console, it will fail with an error. This is due to the fact that part of it in the form of a virtual interface is tied to the tun2socks service , which means it is used. To restart the network service, you must first stop the tun2socks service . But, I think, if you read to the end, for you it is definitely not a problem!

References


  1. Static Routing on 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.

All Articles