Speed ​​up OpenVPN for $9.99* or embed Orange Pi One into a router

Speed ​​up OpenVPN for $9.99* or embed Orange Pi One into a router

Some of us don't surf the internet without a VPN for one reason or another: some need a dedicated IP, and it's easier and cheaper to buy a VPS with two IPs than buying an address from an ISP, some want to access all websites, and not only permitted on the territory of the Russian Federation, the third need IPv6, and the provider does not provide it ...
Most often, a VPN connection is established on the device itself, which is used at a certain moment, which is quite justified if you have only one computer and one phone, and you rarely use them at the same time. If there are many devices in your home network, or, for example, there are those on which VPN cannot be configured, it would be more convenient to set up a tunnel directly on your home router so as not to think about configuring each device individually.

If you have ever installed OpenVPN on your router, you have probably been unpleasantly surprised by its speed. SoCs of even cheap routers pass around gigabit traffic through themselves without any problems, due to the transfer of routing and NAT functions to a separate chip designed exclusively for this task, and the main processors of such routers are rather weak, tk. There is practically no load on them. Such a compromise allows you to achieve a high speed of the router and significantly reduce the price of the finished device - routers with powerful processors are several times more expensive, and are positioned not only as an Internet distribution box, but also as a NAS, torrent downloader and home multimedia system.

My router, TP-Link TL-WDR4300, cannot be called new - the model appeared in mid-2012, and has a 560 MHz processor of the MIPS32 74Kc architecture, the power of which is only enough for 20-23 Mb / s of encrypted traffic via OpenVPN, which by the standards The speed of modern home Internet is quite a bit.
How would we increase the speed of the encrypted tunnel? My router is quite functional, supports 3×3 MIMO, and in general, it works well, I would not want to change it.
Since it is now customary to make 10 MB web pages, write desktop applications in node.js and pack them into a 100 MB file, increase computing power instead of optimizing, we will do something terrible - we will shift the VPN connection to a productive single-board "computer" Orange Pi One, which we install in the router case without taking up existing network and USB ports, for only $9.99*!
* + shipping, + taxes, + for beer, + MicroSD.

openvpn

You can’t call the router’s processor completely weak - it is able to encrypt and hash data using the AES-128-CBC-SHA1 algorithm at a speed of 50 Mb / s, which is noticeably faster than how OpenVPN works, and the modern CHACHA20 stream cipher with the POLY1305 hash even develops 130 megabits per second! Why is the speed of the VPN tunnel so slow? It's all about context switching between user space and kernel space: OpenVPN encrypts traffic and communicates with the outside world in the user context, and the routing itself takes place in the kernel context. The operating system has to constantly switch back and forth, for each received or transmitted packet, and this operation is not fast. This problem is inherent in all VPN applications running through the TUN / TAP driver, and it cannot be said that the low speed problem is caused by poor OpenVPN optimization (although, of course, there are places that need to be redone). Not a single userspace VPN client gives out even a gigabit with encryption disabled on my laptop, to say nothing of systems with a weak processor.

Orange PiOne

Xunlong's Orange Pi One single-board is the best performance/price offer at the moment. For $9.99*, you get a solid quad-core ARM Cortex-A7 processor running (stably) at 1008 MHz, clearly outperforming the Raspberry Pi Zero and Next Thing CHIP in the price range. This is where the pluses end. Xunlong pays exactly zero attention to the software of its boards, and at the time of the launch of One, it did not even provide a board configuration file for sale, not to mention ready-made images. Allwinner, the SoC manufacturer, is also not particularly reverent about supporting its product. They are only interested in the minimum performance in Android 4.4.4, which means that we are forced to use the version 3.4 kernel with Android patches. Fortunately, there are enthusiasts who build distributions, edit the kernel, write code to support boards in the mainline kernel, i.e. actually do the job for the manufacturer, making this shit work acceptable. For my purposes, I chose the Armbian distribution, it is often and conveniently updated (new kernels are installed directly through the package manager, and not by copying files to a special partition, as is usually the case with Allwinner), and it supports most peripherals, unlike the rest.

Router

In order not to load the router's weak processor with encryption and speed up our VPN connection, we can shift this task to the more powerful Orange Pi processor by connecting it to the router in some way. Either Ethernet or USB connection comes to mind - both of these standards are supported by both devices, but I did not want to take up existing ports. Fortunately, there is a way out.

The GL850G USB hub chip used in the router supports 4 USB ports, two of which are not soldered. It is not clear why the manufacturer did not unsolder them, I suppose in order to prevent users from connecting 4 devices with high current consumption (for example, hard drives) at once. The regular power supply of the router is not designed for such a load. Either way, it's in our favor.
Speed ​​up OpenVPN for $9.99* or embed Orange Pi One into a router
In order to get another USB port, it is enough to solder two wires to 8(D-) and 9(D+) or 11(D-) and 12(D+) pins.

Speed ​​up OpenVPN for $9.99* or embed Orange Pi One into a router

However, it's not enough to simply plug in two USB devices and hope everything works by itself, as it would with Ethernet. Firstly, we need to make one of them work in USB Client mode, and not USB Host, and secondly, we need to decide how the devices will determine each other. There are many drivers of the so-called USB Gadgets (after the name of the Linux kernel subsystem) that allow you to emulate various types of USB devices: network adapter, sound card, keyboard and mouse, flash drive, camera, console via serial port. Since our device will work with the network, emulating an Ethernet adapter is best for us.

There are three Ethernet-over-USB standards:

  • Remote NDIS (RNDIS). An outdated standard from Microsoft, used primarily in the days of Windows XP.
  • Ethernet Control Model (ECM). A simple standard that encapsulates Ethernet frames into USB packets. Great for wired modems with a USB connection, where it is convenient to transfer frames without processing, but due to its simplicity and the limitations of the USB bus, it is not very fast.
  • Ethernet Emulation Model (EEM). A smarter protocol that takes into account the limitations of USB and optimally aggregates multiple frames into one, thus increasing throughput.
  • Network Control Model (NCM). The latest protocol. It has the advantages of EEM and further optimizes bus handling.

To make any of these protocols work on our board, as always, we will have to meet some difficulties. Due to the fact that Allwinner is only interested in the Android parts of the kernel, only the Android Gadget works normally - the code that implements adb communication, device export via MTP protocol and flash drive emulation on Android devices. The Android Gadget itself also supports the RNDIS protocol, but it is broken in the Allwinner core. If you try to compile the kernel with any other USB Gadget, the device simply won't show up in the system no matter what you do.
To solve the problem, in a good way, you need to find the place to initialize the USB controller in the code of the android.c Android gadget modified by the developers, but there is also a workaround to make at least Ethernet emulation over USB work:

--- sun8i/drivers/usb/sunxi_usb/udc/sunxi_udc.c 2016-04-16 15:01:40.427088792 +0300
+++ sun8i/drivers/usb/sunxi_usb/udc/sunxi_udc.c 2016-04-16 15:01:45.339088792 +0300
@@ -57,7 +57,7 @@
 static sunxi_udc_io_t g_sunxi_udc_io;
 static u32 usb_connect = 0;
 static u32 is_controller_alive = 0;
-static u8 is_udc_enable = 0;   /* is udc enable by gadget? */
+static u8 is_udc_enable = 1;   /* is udc enable by gadget? */
 
 #ifdef CONFIG_USB_SUNXI_USB0_OTG
 static struct platform_device *g_udc_pdev = NULL;

This patch forcibly turns on USB client mode, which allows you to use regular USB Gadgets from Linux.
Now you should rebuild the kernel with this patch and the necessary gadget. I chose EEM because according to the test results, it turned out to be more productive than NCM.
The Armbian team provides very simple and convenient assembly system for all supported boards in the distribution. Just download it, put our patch in userpatches/kernel/sun8i-default/otg.patch, slightly edit compile.sh and select the required gadget:

Speed ​​up OpenVPN for $9.99* or embed Orange Pi One into a router

The kernel will be assembled into a deb package, which can be easily installed on the board via dpkg.
It remains only to connect the board via USB and configure our new network adapter to receive an address via DHCP. To do this, you need to add something like the following to /etc/network/interfaces:

auto usb0
        iface usb0 inet dhcp
        hwaddress ether c2:46:98:49:3e:9d
        pre-up /bin/sh -c 'echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role'

It is better to set the MAC address manually, because. it will be random every time you reboot your device, which is inconvenient and troublesome.
We connect the MicroUSB cable to the OTG connector, connect the power from the router (it can be supplied to pins 2 and 3 of the comb, and not just to the power connector).

It remains to configure the router. It is enough to install the package with the EEM driver and add our new USB network device to the bridge of the local firewall zone:

opkg install kmod-usb-net-cdc-eem

Speed ​​up OpenVPN for $9.99* or embed Orange Pi One into a router
To route all traffic to the VPN tunnel, you need to either add a SNAT rule to the board's IP address on the router side, or distribute the board's address as the gateway address via dnsmasq. The latter is done by adding the following line to /etc/dnsmasq.conf:

dhcp-option = tag:lan, option:router, 192.168.1.100

where 192.168.1.100 - IP address of your board. Do not forget to register the router address in the network settings on the board itself!

A melamine sponge was used to isolate the board contacts from the router contacts. It turned out something like this:
Speed ​​up OpenVPN for $9.99* or embed Orange Pi One into a router

Conclusion

The network via USB is surprisingly fast: 100-120 Mb / s, I expected less. OpenVPN passes through itself about 70 Mb / s of encrypted traffic, which is also not very much, but enough for my needs. The router cover does not close tightly, leaving a small gap. Aesthetes can unsolder the Ethernet and USB Host connectors from the board, which will allow the cover to close completely, and there will still be room.
Better not to engage in such pornography and buy Turris Omnia.

Source: habr.com

Add a comment