
Някои от нас не използват интернет без VPN по различни причини: на някого му е нужен отделен IP адрес и е по-лесно и по-евтино да закупи VPS с два IP адреса, отколкото да купува адрес от доставчика, някой иска достъп до всички уебсайтове, а не само до разрешените на територията на РС, трети нуждаят се от IPv6, а доставчикът не го предлага...
Най-често VPN връзката се установява на самото устройство, което се използва в даден момент, което е напълно оправдано, ако имате само един компютър и един телефон, и рядко ги използвате едновременно. Ако обаче в домашната ви мрежа има множество устройства или, например, има такива, на които не може да се настрои VPN, би било по-удобно да се настрои тунел направо на домашния рутер, така че да не се налага да мислите за настройката на всяко устройство поотделно.
Ако някога сте инсталирали OpenVPN на своя рутер, вероятно сте били неприятно изненадани от скоростта на работа. SoC на дори евтини рутери без особени проблеми пропускат около гигабитен трафик, благодарение на изнасянето на функциите за маршрутизиране и NAT на отделен чип, предназначен изключително за изпълнение на тази задача, а основните процесори на подобни рутери са доста слаби, тъй като натоварването на тях практически няма. Такъв компромис позволява да се постигне висока скорост на работа на рутера и значително да се намали цената на готовото устройство — рутерите с мощни процесори са много по-скъпи и са позиционирани не само като устройство за разпределение на интернет, но и като NAS, торент-клиент и домашна мултимедийна система.
Моят рутер, TP-Link TL-WDR4300, не може да се нарече нов — моделът се появи през средата на 2012 година и разполага с 560 МГц процесор архитектура MIPS32 74Kc, чиято мощност е достатъчна само за 20-23 Мб/с криптиран трафик чрез OpenVPN, което според мерките за скорост на съвременния домашен интернет е доста малко.
Как можем да увеличим скоростта на криптирания тунел? Моят рутер е доста функционален, поддържа 3×3 MIMO и въобще работи добре, не бих искал да го сменям.
Тъй като в момента е прието да се правят интернет страници от 10 мегабайта, да се пишат десктоп приложения на node.js и да се опаковат в 100-мегабайтови файлове, да се увеличават изчислителните мощности вместо да се оптимизира, ние ще извършим нещо ужасяващо — ще прехвърлим VPN връзката на производителния едноплатков "компютър" Orange Pi One, който ще инсталираме в корпуса на рутера, без да заема съществуващите мрежови и USB портове, всичко това за $9.99*!
* + доставка, + данъци, + за бира, + MicroSD.
OpenVPN
Не можем да наречем процесора на рутера съвсем слаб — той може да криптира и хешира данни с алгоритъма AES-128-CBC-SHA1 със скорост от 50 Мб/с, което е значително по-бързо от това, как работи OpenVPN, а съвременният потоков шифър CHACHA20 с хеш POLY1305 дори достига 130 мегабита в секунда! Защо обаче скоростта на VPN тунела е толкова ниска? Всичко е в превключването на контекста между потребителското пространство и ядрото: OpenVPN криптира трафика и комуникира с външния свят в контекста на потребителя, а самата маршрутизация се извършва в контекста на ядрото. Операционната система постоянно трябва да превключва тук-там за всеки приет или предаден пакет, а тази операция не е бърза. Този проблем е характерен за всички VPN приложения, работещи чрез TUN/TAP драйвер, и не може да се каже, че проблемът с ниската скорост е причинен от лоша оптимизация на OpenVPN (въпреки че, разбира се, има места, които трябва да бъдат преработени). Нито един клиенти на VPN в потребителското пространство не достига дори гигабит с изключено криптиране на моя лаптоп, какво да говорим за системи с слаб процесор.
Orange Pi One
Одноплатният компютър Orange Pi One от компанията Xunlong е най-добрата оферта по отношение на производителност/цена в момента. За 9.99 $ получавате хубав четириядрен процесор ARM Cortex-A7, работещ стабилно на честота 1008 MHz, и определено по-продуктивен от съседите Raspberry Pi Zero и Next Thing C.H.I.P. в същия ценови клас. Тук приключват предимствата. Компанията Xunlong не обръща никакво внимание на софтуера на своите платки, а при старта на One в продажба дори не предостави конфигурационния файл, да не говорим за готови образи. Производителят на SoC, Allwinner, също не проявява особен интерес към поддръжката на продукта си. Те се интересуват само от минималната работоспособност в ОС Android 4.4.4, което означава, че сме принудени да използваме ядрото версия 3.4 с Android-патчове. За щастие, има ентусиасти, които събират дистрибуции, коригират ядрото, пишат код за поддръжка на платките в mainline-ядрото, т.е. всъщност вършат работата на производителя, за да направят това устройство приемливо работещо. За своите цели избрах дистрибуцията Armbian, която се обновява често и удобно (новите ядра се инсталират направо през пакетния мениджър, а не чрез копиране на файлове в специален дял, както обикновено се прави от Allwinner), и поддържа повечето периферни устройства, за разлика от останалите.
Роутер
За да не натоварим слабия процесор на рутера със шифроване и да ускорим нашето VPN-съединение, можем да прехвърлим тази задача на по-производителния процесор Orange Pi, като го свържем с рутера по някакъв начин. Мисля, че може да се свърже или чрез Ethernet, или чрез USB — и двата стандарта се поддържат от двете устройства, но не исках да заема вече наличните портове. Щастливи сме, че има решение.
Чипът на USB-хъба GL850G, който се използва в рутера, поддържа работа с 4 USB-порта, от които два не са разпаяни. Не е ясно защо производителят не е разпаял портовете, предполагам, че е за да не позволи на потребителите да свържат веднага 4 устройства с висока консумация на ток (например, твърди дискове), тъй като стандартният захранващ блок на рутера не е проектиран за такава натовареност. Във всеки случай, това е в наша полза.

За да получим още един USB-порт, е достатъчно да добавим два проводника към 8(D-) и 9(D+) или 11(D-) и 12(D+) пиновете.

Въпреки че не е достатъчно просто да свържете два USB устройства и да се надявате, че всичко ще работи само по себе си, както би се случило с Ethernet. Първо, трябва да накараме едно от тях да работи в режим USB Client, а не USB Host; второ, трябва да определим как устройствата ще се разпознават взаимно. Съществуват много драйвъри на т. нар. USB Gadgets (по названието на подсистемата в ядрото на Linux), които позволяват емулация на различни типове USB устройства: мрежов адаптер, звукова карта, клавиатура и мишка, флаш памет, фотоапарат, конзола чрез последователен порт. Тъй като нашето устройство ще работи с мрежата, е най-добре да използваме емулация на Ethernet адаптер.
Съществуват три стандарта Ethernet-over-USB:
- Remote 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 Gadget 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 и да изберете необходимия гаджет:

Ядрото ще се компилира в 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 устройство в бриджа на локалната защитна зона:
opkg install kmod-usb-net-cdc-eem
За да маршрутизирате целия трафик в VPN тунел, трябва или да добавите SNAT правило за IP адреса на платката от страната на рутера, или да зададете адреса на платката като адрес на шлюза през dnsmasq. Последното се постига чрез добавяне на следния ред в /etc/dnsmasq.conf:
dhcp-option = tag:lan, option:router, 192.168.1.100където 192.168.1.100 — IP адресът на вашата платка. Не забравяйте да зададете адреса на маршрутизатора в мрежовите настройки на самата платка!
За изолация на контактите на платката от контактите на рутера беше използвана меламинова гъба. Получи се ето така:

Заключение
Мрежата работи изненадващо бързо през USB: 100-120 Мб/с, очаквах по-малко. OpenVPN пропуска около 70 Мб/с криптиран трафик, което не е много, но е достатъчно за нуждите ми. Капакът на рутера не се затваря плътно, оставяйки малък процеп. Естетите могат да отстранят Ethernet и USB Host портовете от платката, което ще позволи капакът да се затвори напълно и ще остане допълнително място.
А по-добре е да не се занимава с подобна порнография и да се купи .
Източник: habr.com
