Прискорюємо OpenVPN за $9.99* або вбудовуємо Orange Pi One у роутер

Прискорюємо OpenVPN за $9.99* або вбудовуємо Orange Pi One у роутер

Деякі з нас не користуються інтернетом без VPN з тих чи інших причин: комусь потрібен виділений IP, і простіше і дешевше купити VPS з двома IP, ніж купувати адресу у провайдера, хтось хоче отримувати доступ до всіх веб-сайтів, а не лише дозволеним на території РФ, третім потрібен IPv6, а провайдер його не надає.
Найчастіше VPN-з'єднання встановлюють на самому пристрої, який використовується в певний момент, що цілком виправдано, якщо у вас тільки один комп'ютер і один телефон, і їх рідко використовуєте одночасно. Якщо ж у вашій домашній мережі безліч пристроїв, або, наприклад, є такі, на яких VPN налаштувати не можна, було б зручніше піднімати тунель прямо на домашньому роутері, щоб не замислюватися про налаштування кожного пристрою окремо.

Якщо ви хоч раз встановлювали OpenVPN на свій маршрутизатор, ви, ймовірно, були неприємно вражені швидкістю його роботи. SoC'і навіть дешевих роутерів без особливих проблем пропускають через себе навкологігабітний трафік, за рахунок винесення функцій маршрутизації та NAT на окремий чіп, призначений винятково для виконання цього завдання, а основні процесори таких роутерів досить слабкі, тому що ця функція може бути недоступною. навантаження на них ніякої немає. Такий компроміс дозволяє досягти високої швидкості роботи роутера і помітно знизити ціну готового пристрою - маршрутизатори з потужними процесорами коштують у кілька разів дорожче, і позиціонуються вже не тільки як коробка для роздачі інтернету, а й як NAS, торрентокачалки та домашньої мультимедіа-системи.

Мій роутер, TP-Link TL-WDR4300, не можна назвати новим - модель з'явилася в середині 2012 року, і має 560 МГц-процесор архітектури MIPS32 74Kc, потужності якого вистачає лише на 20-23 Мб/с шифрованого трафіку через OpenVPN, що по шифрованого трафіку через OpenVPN. швидкості сучасного домашнього інтернету зовсім небагато.
Як би підвищити швидкість шифрованого тунелю? Мій роутер досить функціональний, підтримує 3×3 MIMO, та й взагалі добре працює, не хотілося б його міняти.
Так як зараз прийнято робити 10-мегабайтні інтернет-сторінки, писати десктопні програми на node.js і пакувати їх у 100-мегабайтний файл, нарощувати обчислювальні потужності замість оптимізації, ми зробимо щось жахливе - перекладемо VPN-підключення на продуктивний одноплатний комп'ютер Pi One, який встановимо в корпус роутера, не займаючи існуючі мережеві та USB-порти всього за $9.99*!
* + Доставка, + податки, + на пиво, + MicroSD.

OpenVPN

Не можна назвати процесор роутера зовсім слабким - він здатний шифрувати і хешувати дані алгоритмом AES-128-CBC-SHA1 зі швидкістю 50 Мб/с, що помітно швидше за те, як працює OpenVPN, а сучасний потоковий шифр CHACHA20 з хешем POLY1305 і мегабіт за секунду! Чому ж швидкість VPN-тунелю така невисока? Вся справа в перемиканні контексту між простором користувача та простором ядра: OpenVPN шифрує трафік і спілкується із зовнішнім світом у контексті користувача, а в контексті ядра відбувається сама маршрутизація. Операційній системі доводиться постійно перемикатися туди, то сюди, на кожен прийнятий або переданий пакет, а ця операція нешвидка. Ця проблема властива всім VPN-додаткам, що працюють через TUN/TAP-драйвер, і не можна сказати, що проблема низької швидкості викликана поганою оптимізацією OpenVPN (хоча, звичайно, там є місця, які потрібно переробити). Жоден userspace VPN-клієнт не видає навіть гігабіта з відключеним шифруванням на моєму ноутбуці, що вже говорити про системи зі слабким процесором.

Помаранчевий Пі Один

Одноплатник Orange Pi One від компанії Xunlong — найвигідніша пропозиція щодо співвідношення продуктивність/ціна на даний момент. За $9.99* ви отримуєте добротний чотириядерний процесор ARM Cortex-A7, що (стабільно) працює на частоті 1008 МГц, і явно продуктивніша за сусідів Raspberry Pi Zero і Next Thing CHIP за ціновою категорією. На цьому плюси закінчуються. Компанія Xunlong приділяє софту своїх плат як нуль уваги, і на момент запуску One у продаж не надавала навіть файл конфігурації плати, не кажучи вже про готові образи. Allwinner – виробник SoC – теж не особливо трепетно ​​ставиться до підтримки свого продукту. Їх цікавить лише мінімальна працездатність в ОС Android 4.4.4, отже, ми змушені використовувати ядро ​​версії 3.4 з Android-патчами. На щастя, є ентузіасти, які збирають дистрибутиви, правлять ядро, пишуть код підтримки плат у mainline-ядре, тобто. фактично роблять роботу за виробника, змушуючи це гівно прийнятно працювати. Для своїх цілей я вибрав дистрибутив Armbian, він часто і зручно оновлюється (нові ядра встановлюються прямо через пакетний менеджер, а не копіюванням файлів на спеціальний розділ, як це зазвичай буває Allwinner), та й підтримує більшість периферії, на відміну від інших.

Роутер

Для того, щоб не завантажувати слабкий процесор роутера шифруванням і прискорити наше VPN-з'єднання, ми можемо перекласти це завдання на плечі продуктивнішого процесора Orange Pi, підключивши його до роутера будь-яким чином. На думку спадає підключення або по Ethernet, або по USB — обидва ці стандарти підтримуються обома пристроями, але не хотілося займати вже існуючі порти. На щастя, вихід є.

Мікросхема USB-хабу GL850G, яка використовується в роутері, підтримує роботу 4 USB-портів, два з яких не розпаяно. Неясно, чому виробник не став розпаювати їх, припускаю, щоб не дати можливість користувачам підключити відразу 4 пристрої з високим споживанням струму (наприклад, жорстких дисків), т.к. штатний блок живлення роутера не розрахований на таке навантаження. У будь-якому разі це нам на руку.
Прискорюємо OpenVPN за $9.99* або вбудовуємо Orange Pi One у роутер
Для того, щоб отримати ще один USB-порт, достатньо допаяти два дроти до 8(D-) і 9(D+) або 11(D-) та 12(D+) пін.

Прискорюємо OpenVPN за $9.99* або вбудовуємо Orange Pi One у роутер

Однак недостатньо просто так підключити два USB-пристрої і сподіватися, що все запрацює само собою, як це сталося б з Ethernet. По-перше, нам потрібно змусити одного з них працювати в режимі USB Client, а не USB Host, по-друге, нам потрібно визначитися з тим, як пристрої визначатимуть один одного. Існує безліч драйверів так званих USB Gadgets (назвою підсистеми Linux-ядра), які дозволяють емулювати різні типи USB-пристроїв: мережевий адаптер, аудіокарту, клавіатуру і мишу, флешку, фотоапарат, консоль через послідовний порт. Оскільки наш пристрій буде працювати з мережею, нам найкраще підійде емуляція Ethernet-адаптера.

Існує три стандарти Ethernet-over-USB:

  • Віддалений NDIS (RNDIS). Застарілий стандарт від Microsoft використовувався переважно за часів Windows XP.
  • Ethernet Control Model (ECM). Простий стандарт, який інкапсулює Ethernet-фрейми у USB-пакети. Відмінно підходить для проводових модемів з USB-підключенням, де зручно передавати кадри без обробки, але через свою простоту та обмеження USB-шини працює не надто швидко.
  • Ethernet Emulation Model (EEM). Розумніший протокол, який враховує обмеження USB і оптимально агрегує кілька кадрів в один, підвищуючи таким чином пропускну здатність.
  • Network Control Model (NCM). Найновіший протокол. Має переваги EEM і ще більше оптимізує роботу з шиною.

Щоб змусити працювати будь-який із цих протоколів на нашій платі, як завжди, доведеться зустрітися з деякими труднощами. Через те, що Allwinner цікавлять тільки Android-частини ядра, нормально працює тільки Android Gadget - той код, який реалізує зв'язок з adb, експорт пристрою за протоколом MTP та емуляцію флешки на Android-пристроях. Сам Android Gadget підтримує протокол RNDIS, але в ядрі Allwinner він зламаний. Якщо ви спробуєте скомпілювати ядро ​​з іншим USB Gadget, пристрій просто не з'явиться в системі, що б ви не робили.
Для вирішення проблеми, по-хорошому, необхідно знайти місце ініціалізації USB-контролера в модифікованому розробниками кодом Android-гаджета android.c, але існує й обхідний маневр, щоб змусити працювати, як мінімум, емуляцію Ethernet через USB:

--- 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;

Цей патч силоміць включає режим USB-клієнта, що дозволяє використовувати звичайні USB Gadgets з Linux.
Тепер слід перезбирати ядро ​​з цим патчем та необхідним гаджетом. Я вибрав EEM, тому що. за результатами тестів він виявився продуктивнішим за NCM.
Команда Armbian надає дуже просту та зручну збірну систему для всіх підтримуваних плат у дистрибутиві. Достатньо завантажити її, покласти наш патч у userpatches/kernel/sun8i-default/otg.patch, трохи відредагувати compile.sh та вибрати необхідний gadget:

Прискорюємо OpenVPN за $9.99* або вбудовуємо Orange Pi One у роутер

Ядро збереться в deb-пакет, який не важко встановити на плату через dpkg.
Залишається тільки підключити плату USB і налаштувати наш новий мережевий адаптер на отримання адреси через DHCP. Для цього необхідно додати приблизно наступне в /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'

MAC-адреса краще задати вручну, т.к. він буде випадковим при кожному перезавантаженні пристрою, що незручно та клопітно.
Підключаємо MicroUSB-кабель до OTG-роз'єму, підключаємо живлення з роутера (його можна подавати на 2 та 3 піни гребінки, а не тільки на роз'єм живлення).

Залишилося налаштувати роутер. Достатньо встановити пакет з EEM-драйвером і додати наш новий мережний USB-пристрій до бриджу локальної firewall-зони:

opkg install kmod-usb-net-cdc-eem

Прискорюємо OpenVPN за $9.99* або вбудовуємо Orange Pi One у роутер
Щоб маршрутизувати весь трафік у VPN-тунель, потрібно або додати SNAT-правило на IP-адресу плати на стороні роутера, або роздавати адресу шлюзу адресу плати через dnsmasq. Останнє робиться додаванням наступного рядка до /etc/dnsmasq.conf:

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

де 192.168.1.100 - IP-адреса вашої плати. Не забудьте прописати адресу машрутизатора у налаштуваннях мережі на самій платі!

Для ізоляції контактів плати від контактів роутера використовувалася меламінова губка. Вийшло якось так:
Прискорюємо OpenVPN за $9.99* або вбудовуємо Orange Pi One у роутер

Висновок

Працює мережа через USB напрочуд швидко: 100-120 Мб/с, я очікував меншого. OpenVPN пропускає через себе близько 70 Мб/с шифрованого трафіку, що теж не дуже багато, але для моїх потреб вистачає. Кришка маршрутизатора закривається нещільно, залишаючи невеликий проміжок. Естети можуть випаяти Ethernet і USB Host-роз'єм у плати, що дозволить кришці закритися повністю, і ще місце залишиться.
А краще не займатися такою порнографією та купити Turris Omnia.

Джерело: habr.com

Додати коментар або відгук