[Перевод] Хостинг блога на GPS/LTE-модеме

image

GPS/WWAN/LTE-модем телефона PinePhone


В процессе разработки ПО на PinePhone я наткнулся на любопытное сообщение в dmesg:
[   25.476857] modem-power serial1-0: ADB KEY is '41618099' (you can use it to unlock ADB access to the modem)

Для контекста скажу, что в PinePhone есть модем Quectel EG25-G, отвечающий за GPS и беспроводную связь PinePhone. Это оборудование — один из немногих компонентов телефона с закрытыми исходниками.

Когда я увидел это сообщение и упоминание ADB, я сразу же подумал об Android Debug Bridge, то есть о ПО, стандартно используемое для общения с Android-устройствами. Я подумал: «Разумеется, это не может быть тот самый ADB». Ну, оказалось, что так оно и есть.
Это сообщение связано со статьёй, в которой подробно описывается данный модем. Также оно связано с утилитой-разблокировщиком, которое выводит на печать AT-команды, чтобы обеспечить adbd модема.

$ ./qadbkey-unlock 41618099
AT+QADBKEY="WUkkFzFSXLsuRM8t"
AT+QCFG="usbcfg",0x2C7C,0x125,1,1,1,1,1,1,0

Их можно отправлять на модем при помощи screen:
# screen /dev/ttyUSB2 115200

По какой-то причине мой ввод не возвращал данные, но экранная сессия дважды вывела «OK», показывая, что выполнила команды успешно.

После настройки правил udev и adb на моей «хост-машине», то есть на PinePhone, модем начал выдавать вывод для adb devices, который я мог передать в оболочку:

$ adb devices
List of devices attached
(no serial number)	device

$ adb shell
/ #

Так как adbd был запущен в root-режиме, я передал вывод в root-оболочку. Отлично.

Оказалось, что в модеме работает собственная ОС, полностью независимая от остальной части ОС PinePhone. С последними обновлениями в нём работает Linux 3.18.44.

Запускаем веб-сервер


По какой-то причине я посчитал, что будет забавно запустить на этом устройстве свой блог. Так как мы работаем с ограниченными ресурсами (примерно 48 МБ накопителя и тот же объём памяти), а мой блог состоит только из статичных страниц, я решил, что нечто вроде nginx (каким бы легковесным он ни был) окажется пустой тратой ресурсов для моей цели.

Мне показалось, что моим требованиям хорошо соответствует darkhttpd. Единственный двоичный файл, никаких внешних зависимостей, выполняет только запросы GET и HEAD. Идеально.

Я воспользовался тулчейном armv7l-linux-musleabihf-cross для кросс-компиляции этого сервера для ARMv7, и статически скомпоновал его с musl. При помощи adb push мне с лёгкостью удалось передать двоичный файл и ресурсы моего сайта в папку /usrdata модема, к которой примонтирован раздел на 50 МБ с возможностью записи.

HTTP-сервер работает замечательно. Я решил использовать ADB, чтобы открыть HTTP-порт для своего PinePhone:

$ adb forward tcp:8080 tcp:80

Так как перенаправляемые через ADB порты привязаны только к loopback-интерфейсу, я вручную открыл его для внешних соединений:
# sysctl -w net.ipv4.conf.all.route_localnet=1
# iptables -t nat -I PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 127.0.0.1:8080

После чего смог получить доступ к своему блогу по адресу http://pine:8080/. Круто!

Производительность?


Я запустил iperf для перенаправления портов через ADB, чтобы проверить, какой производительности удалость добиться.
$ iperf -c localhost
------------------------------------------------------------
Client connecting to localhost, TCP port 5001
TCP window size: 2.50 MByte (default)
------------------------------------------------------------
[  3] local 127.0.0.1 port 44230 connected with 127.0.0.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.6 sec  14.4 MBytes  11.4 Mbits/sec

То есть примерно 10 Мбит/с. Not great, not terrible.

Сам PinePhone подключён к сети через USB (примечание: чтобы сетевое подключение через USB заработало, мне пришлось убрать с платы два компонента). Ради интереса я запустил iperf и для этого соединения:

$ iperf -c 10.15.19.82
------------------------------------------------------------
Client connecting to 10.15.19.82, TCP port 5001
TCP window size:  136 KByte (default)
------------------------------------------------------------
[  3] local 10.15.19.100 port 58672 connected with 10.15.19.82 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.4 sec  25.8 MBytes  20.7 Mbits/sec

Я ожидал большего, но на самом деле это неважно, потому что самым узким местом является соединение, перенаправляемое через ADB.

Прочие рассуждения


Я задался вопросом о защищённости модема. Оказалось, что многие AT-команды используют в модеме system(). Подозреваю, что некоторые из этих AT-команд могут быть уязвимыми к инъекциям команд, но более глубокого изучения не проводил. На самом деле это неважно, поскольку передача на root-оболочку при помощи ADB реализуется очень просто.

На первый взгляд, это кажется идеальным способом обеспечения устойчивости вредоносного кода. Имея root-доступ к хосту, вредоносный код может встроить себя в модем, что позволит ему пережить переустановку ОС хоста, перехватывать коммуникации или отслеживать местоположение устройства. Ущерб частично снижается благодаря тому, что всё взаимодействие с ОС хоста производится через USB и I2S, и только когда ОС хоста его инициирует, поэтому вредоносный код в модеме не сможет напрямую взаимодействовать с ОС хост-устройства.


На правах рекламы


Эпичные серверы для размещения сайтов и не только! Дешёвые VDS на базе новейших процессоров AMD EPYC и хранилища на основе NVMe дисков от Intel для размещения проектов любой сложности, от корпоративных сетей и игровых проектов до лендингов и VPN. Вы можете создать собственную конфигурацию сервера в пару кликов!

Подписывайтесь на наш чат в Telegram.

8p3vz47nluspfyc0axlkx88gdua.png

© Habrahabr.ru