Превращаем недорогой роутер в домашний сервер

Этот пост был написан примерно год назад и вообще для вражеского сайта и не совсем соответствует тематике ЕЕ. Но, думаю, может быть интересен. На вражеском сайте пост стал недоступен после того, как я с гневом выпилил оттуда свой аккаунт после очередного произвола НЛО.

Так что пускай тут полежит, в моём персональном блоге. 🙂

Не секрет, что стоимость роутера значительно зависит от возможностей встроенного программного обеспечения. Так что, покупая недорогое устройство, многие пользователи не ждут от родной прошивки ничего хорошего и устанавливают альтернативную прошивку. Но, как правило, на этом всё и заканчивается. Пользователь изучает встроенный веб-интерфейс и радуется новым возможностям поумневшего устройства. Однако, прошивка роутера — полноценная операционная система на базе Linux, позволяющая воплотить многие задумки, выходящие далеко за рамки привычной функциональности роутера.



В этом посте я хочу поделиться своим опытом по созданию сервера на основе роутера D-Link DIR-320. На роутере были подняты Веб-сервер, FTP, настроена видеотрансляция. Хотя статья и предполагает использование DIR-320, для другого роутера процесс настройки будет отличаться незначительно.

Аппаратное обеспечение

Я использовал роутер DIR-320. Данный девайсик имеет MIPS32-микроконтроллер Broadcom BCM5354 с тактовой частотой 240 МГц, оперативную память объёмом 32 МБ, энергонезависимую память объёмом 4 МБ. Сетевые интерфейсы, 2.4 ГГц RF-модуль, USB-контроллер интегрированы в микроконтроллер. Ещё в устройстве установлен 100-мегабитный свитч на 4 порта. Кстати, микроконтроллер достаточно сильно грелся, но после того, как на него был посажен на термопасту небольшой медный радиатор, температура снизилась до нормальных 40-50 градусов. Кроме того, на плате не был установлен экран на высокочастотном модуле, хотя и была предусмотрена площадка для его пайки. Впрочем, эти небольшие недостатки конструкции компенсируются сравнительно низкой ценой устройства, хорошим потенциалом для моддинга, поддержкой альтернативных прошивок, лёгкостью восстановления стандартной прошивки после неудачных экспериментов. Кроме роутера был использован 4-портовый USB-хаб Manhattan, UVC-камера A4-Tech PK-750MJ на китайской микросхеме VC0332, USB-флешка Kingston на 2 ГБ, пара патч-кордов по 1,5 м. Питание осуществляется от стандартного блока питания на 2 Ампера из комплекта роутера. Запаса мощности вполне хватает для питания дополнительных устройств. При подключении более серьёзных потребителей (например, HDD) желательно установить блок питания по приличней, Meanwell’овский юнит например.

Роутер

Выбор прошивки

Первой прошивкой, на которую я обратил внимание, была DD-WRT. Эта прошивка порадовала качеством, стабильностью и обширным набором дополнительных пакетов — Optware. DD-WRT поддерживает множество устройств, легко устанавливается, имеет удобный веб-интерфейс, множество возможностей доступно сразу после заливки прошивки в роутер. Однако DD-WRT основана на старом ядре 2.4, что накладывает серьёзные ограничения. Например, ядро 2.4 не поддерживает модуль uvcvideo, который требовался мне для подключения камеры. Погуглив, я узнал о прошивке OpenWrt. Последний релиз OpenWrt 10.03 под кодовым именем Backfire, вышедший 8 апреля 2010 г, поддерживает ядро 2.6.32. Для этой прошивки создан набор дополнительных пакетов — X-Wrt, в котором можно найти очень много полезного портированного софта и админку WebIf. Главная особенность OpenWrt — перезаписываемая файловая система, которая монтируется поверх стандартной файловой системы, что позволяет устанавливать пакеты в роутер и выполнять конфигурирование привычным редактированием файлов. Возможно монтирование как части энергонезависимой памяти роутера, незанятой прошивкой (с использованием файловой системы JFFS2), так и внешнего носителя. Для установки пакетов используется менеджер opkg. OpenWrt вместе с дополнительными пакетами распространяется в исходниках.

Сборка прошивки

Нам понадобится любая операционная система на основе Linux. Я использовал Arch Linux.

Для получения исходников, нужно установить subversion:

$ sudo pacman -S subversion

Скачиваем Buildroot OpenWrt:

$ mkdir ~/openwrt && cd ~/openwrt
$ svn co svn
://svn.openwrt.org/openwrt/branches/backfire

Скачиваем и устанавливаем дополнительные пакеты и патчи:

$ cd backfire
$
./scripts/feeds update && ./scripts/feeds install -a

Проверяем наличие всех нужных для сборки пакетов и инициализируем конфигурацию прошивки:

$ make defconfig

Конфигурируем прошивку:

$ make menuconfig

В процессе конфигурирования, нужно выбрать систему, пакеты, и настроить будущую прошивку. В принципе, базовая конфигурация прошивки вполне работоспособна, нам нужно просто доконфигурировать прошивку по вкусу.

Меню настройки

Выбираем систему:

TargetSystem-> BCM947xx/953xx--выбираемвариантдлянашего BCM5354 сядром2.6

Выбирать пакеты можно как для установки в прошивку, так и просто для сборки. Пакеты, собранные без установки образуют наш мини-репозиторий, из которого их можно будет устанавливать уже после заливки прошивки в роутер. Памяти в DIR-320 всего 4 МБ, причём обязательно должно остаться немного свободного места для использования JFFS2. Так что будем устанавливать минимально необходимый набор пакетов, а остальное соберём для последующей установки на внешний носитель. Чтобы выбрать пакет для установки в прошивку, нужно нажать Y. Я добавил в прошивку пакеты, требуемые для монтирования флешки:

KernelModules-> USB Support-> core, usb2, ohci --дляподдержкиконтроллеров USB 2.0
KernelModules-> USB Support-> storage --дляподдержки USB-накопителей
KernelModules->Filesystems-> ext3 --выбираемнужныефайловыесистемы
BaseSystem-> block-mount --длямонтированиячерез fstab
Utilities-> disc -> block-extroot --длямонтированияповерхфайловойсистемы
Utilities->Editors-> nano --удобныйтекстовыйредактордляконфигурированиясистемы

Также, добавил веб-админку. Без админки не удастся установить пароль для входа по ssh:

Administration-> webif -> webif, webif-applications --веб-админка

Затем, выбираем пакеты для сборки без установки. Не стоит выбирать много лишних пакетов, чтобы время сборки не увеличивалось до неразумных пределов. Чтобы выбрать пакет для сборки без установки, нужно нажать M. Многие пакеты можно установить и из основного репозитория, однако нужные модули ядра стоит собрать, т.к. в репозитории могут быть несовместимые версии. Я выбрал модули ядра, необходимые для подключения UVC-камеры — kmod-video-core и kmod-video-uvc.

Также можно настроить некоторые параметры прошивки, например сетевой адрес по умолчанию. Я установил адрес 192.168.0.1 (адрес роутера по умолчанию — 192.168.1.1):

Image Configuration -> LAN IP Address -> 192.168.0.1

При необходимости, можно сконфигурировать ядро. Я оставил всё по умолчанию.

$ make kernel_menuconfig

Собираем прошивку:

$ make

В процессе сборки прошивки также будут скачиваться и собираться необходимые инструменты для кросс-компиляции, скачиваться исходники ядра, пакетов и т.д. Сборка займёт от 30 минут до нескольких часов, в зависимости от производительности сети и компьютера. После завершения сборки, в папке bin будут находиться созданные образы прошивки в различном формате и собранные пакеты. Нам понадобится образ прошивки в формате squashfs — openwrt-brcm47xx-squashfs.trx.

Заливка прошивки

Для заливки прошивки понадобится TFTP-клиент (неважно, под Linux или Windows), я использовал GUI’шную утилитку под Windows, которую можно найти на сайте DD-WRT. Нужно подключить PC к LAN-порту роутера, выставить на сетевом интерфейсе PC статический IP 192.168.0.10 и маску подсети 255.255.255.0. В TFTP-клиенте выбрать файл прошивки и выставить IP сервера 192.168.0.1. Включить роутер и дождаться линка, затем отправить прошивку в роутер. Загрузчик ждёт прошивку в течении пары секунд, так что, возможно, понадобится несколько попыток, также, при необходимости, стоит сразу разобраться с фаерволом, чтобы отправить прошивку без лишней задержки. После того, как прошивка будет отправлена на роутер, нужно подождать пару минут, пока загрузчик не завершит внутренний цикл прошивки и не включится диагностический светодиод.

Перед заливкой новой прошивки стоит запастись оригинальной прошивкой — если заливка пройдёт неудачно, можно будет вернуть оригинальную прошивку через консоль восстановления. Для этого нужно включить роутер, удерживая Reset, затем зайти браузером на 192.168.0.1.

После завершения прошивки, настраиваем сетевой интерфейс компа на получения адреса с помощью DHCP, перезагружаем роутер. OpenWrt загружается несколько дольше оригинальной прошивки, причём диагностический светодиод светится во время загрузки и гаснет при завершении. Если всё прошло успешно, заходим браузером на роутер. На этом этапе не обязательно настраивать роутер — после подключения внешнего накопителя, настройки будут храниться на нём и придётся заново настраивать. Достаточно лишь установить пароль.

Подготовка накопителя

Накопитель нужно разбить на разделы fdisk’ом и отформатировать. Я создал 3 раздела — под систему, под домашние директории и под своп. Не забудь заменить /dev/sdb на имя съёмного накопителя в своей системе:

Disk/dev/sdb:2004 MB,2004877312 bytes
62 heads,62 sectors/track,1018 cylinders
Units= cylinders of 3844*512=1968128 bytes
Disk identifier:0xa8afe1b3

DeviceBootStartEndBlocksIdSystem
/dev/sdb1 1255488281+83Linux
/dev/sdb2 2559921416015+83Linux
/dev/sdb3 99210195256782Linux swap / Solaris

Форматируем:

$ mkfs.ext3 /dev/sdb1
$ mkfs
.ext3 /dev/sdb2
$ mkswap
/dev/sdb3

Настройка прошивки для загрузки с внешнего накопителя

Заходим на роутер SSH-клиентом, используя логин root и пароль, установленный через веб-админку. Редактируем файл /etc/config/fstab.

$ nano /etc/config/fstab

Редактируем одну секцию «mount» для монтирования раздела накопителя поверх основной файловой системы. Для монтирования других разделов, будет использоваться файл fstab, хранящийся на внешнем накопителе:

config mount
option target
/
option fstype ext3
option enabled_fsck
0
option device
/dev/sda1
option options rw
,sync
option is_rootfs
1
option enabled
1

Перезагружаем роутер, заходим в веб-админку. Если всё прошло успешно, админка должна снова попросить установить пароль — устройство успешно смонтировалось и настройки теперь хранятся на нём.

Настройка прошивки

Меню настройки

Заходим на роутер SSH-клиентом, создаём точку монтирования для домашних директорий:

$ mkdir /home

При желании установить собранные вместе с прошивкой пакеты, расшариваем их (папку bin Buildroot’а) FTP-сервером, затем прописываем наш мини-репозиторий в файле /etc/opkg.conf, добавив строку:

src/gz mypackages ftp://(адрес сервера)/brcm47xx/packages

Обновляем список пакетов:

$ opkg update

Если при обновлении будут получены списки пакетов из основного репозитория, их можно удалить:

$ cd /var/opkg-lists
$ rm X
-Wrt packages

Устанавливаем нужные пакеты:

$ opkg install kmod-input-core kmod-video-core kmod-video-uvc

Основное конфигурирование удобно выполнять через веб-админку. Устанавливаем имя хоста, часовой пояс, добавляем точки монтирования, настраиваем сетевые интерфейсы и т.д. Я смонтировал раздел для домашних директорий с опциями async и noatime, чтобы продлить жизнь флешке. Перезагружаем роутер и проверяем результат:

$ df -h
FilesystemSizeUsedAvailableUse%Mounted on
/dev/root 2.0M2.0M0100%/rom
tmpfs 14.5M 72.0K 14.5M 0% /
tmp
tmpfs
512.0K0512.0K0%/dev
/
dev/sda1 461.8M19.8M418.1M5%/overlay
mini_fo:/
overlay 2.0M2.0M0100%/
/
dev/sda2 1.3G558.4M733.6M43%/home

Устанавливаем FTP-сервер

Создадим группу админов сервера:

$ echo web:x:101:>>/etc/group

Создадим пользователя ftp для анонимного входа, добавим его в группу nogroup (65534), и пользователя ftpadmin для администрирования файлов, доступных по FTP.

$ echo ftpadmin:*:102:101:ftpadmin:/home/srv/ftp:/bin/ash >>/etc/passwd
$ echo ftp
:*:103:65534:ftp:/home/srv/ftp:/bin/ash >>/etc/passwd
$ mkdir
-p /home/srv/ftp
$ chgrp
-R web /home/srv
$ chown ftpadmin
/home/srv/ftp

Зададим пароль для пользователя ftpadmin

$ passwd ftpadmin

Установим pure-ftpd — быстрый и лёгкий FTP-сервер

$ opkg update
$ opkg install pure
-ftpd

Настройки сервера находятся в файле /etc/config/pure-ftpd. Разрешим анонимный вход и выберем отдельный лог отредактировав следующие строки:

option noanonymous '0'
option anonymouscantupload
'1'
option syslogfacility
'none'
option altlog
'stats:/var/log/pureftpd.log'
option enabled
'1'

Также удалим опцию peruserlmits, чтобы убрать ограничения на количество входов пользователей.

Запустим сервер:

$ /etc/init.d/pure-ftpd start

Зайдём в веб-админку на вкладку Services и отметим pure-ftpd для автоматического запуска. Чтобы сервер был доступен из интернета, нужно зайти на вкладку Firewall и открыть 21 порт.

Устанавливаем веб-сервер

Создадим домашнюю директорию для файлов и пользователя, который будет владеть этой директорией:

$ echo wwwadmin:*:101:101:wwwadmin:/home/srv/www:/bin/ash >>/etc/passwd
$ mkdir
/home/srv/www
$ chgrp web
/home/srv/www
$ chown wwwadmin
/home/srv/www

Зададим пароль для пользователя wwwadmin:

$ passwd wwwadmin

Установим веб-сервер lighttpd с нужными плагинами:

$ opkg update
$ opkg install lighttpd lighttpd
-mod-cgi lighttpd-mod-access lighttpd-mod-redirect

Установим PHP:

$ opkg install libsqlite3 php5-cgi php5-mod-pdo php5-mod-sqlite php5-mod-gd php5-mod-session

Сконфигурируем lighttpd. Настройки хранятся в файле /etc/lighttpd/lighttpd.conf.

Подключим нужные нам плагины:

server.modules =(
"mod_cgi",
"mod_access",
"mod_redirect"
)

Установим директорию для документов:

server.document-root ="/home/srv/www"

Зададим имена документов по-умолчанию:

index-file.names =("index.htm","index.php")

Укажем CGI-обработчик для PHP:

cgi.assign =(".php"=>"/usr/bin/php-cgi")

Желательно указать UID и GID для сервера, чтобы он не работал с правами суперпользователя:

server.username ="wwwadmin"
server
.groupname ="web"

Настроим PHP, отредактировав файл /etc/php.ini. Подключим нужные модули, раскоментировав соответствующие строки:

extension=pdo.so
extension
=gd.so
extension
=session.so
extension
=sqlite.so

Изменим параметр doc_root на пустую строку, иначе интерпретатор будет искать скрипты не в том месте:

doc_root =

Чтобы сервер заработал, нужно сначала перевесить веб-админку роутера с 80 порта на какой-нибудь другой порт. Запустим сервер:

$ /etc/init.d/lighttpd start

Создадим в /home/srv/www файл test.php с таким содержимым:

<?php phpinfo();?>

Откроем 192.168.0.1/test.php. Если всё прошло удачно, увидим таблицу с настройками PHP:

Перейдём на вкладку Services веб-админки и разрешим автоматический запуск lighttpd. На вкладке Firewall откроем 80 порт чтобы сервер был виден из интернета.

Настраиваем видеотрансляцию

Вебка

Для начала, нужно установить нужные для камеры модули и убедиться, что камера успешно подхвачена системой:

$ ls /dev/video*
/dev/video0

Для видеотрансляции будем использовать пакет MJPEG-Streamer. Это довольно тяжелый пакет, но его можно немного твикнуть.

Вернёмся к Buildroot’у. Получим исходники пакета:

$ cd ~/openwrt/backfire
$ make package
/mjpg-streamer/clean
$ make package
/mjpg-streamer/prepare

Поправим код для сжатия в JPEG. Путь может немного отличаться для разных версий пакета и библиотек:

$ nano build_dir/target-mipsel_uClibc-0.9.30.1/mjpg-streamer-r94/plugins/input_uvc/jpeg_utils.c

Найдём в коде строку инициализации параметров сжатия:

jpeg_set_defaults (&cinfo);

После этой строки можно переопределить некоторые параметры сжатия JPEG. Выберем быстрый целочисленный метод для DCT:

cinfo.dct_method = JDCT_IFAST;

Сохраним изменения, скомпилируем пакет, обновим индекс пакетов:

$ make package/mjpg-streamer/compile V=99
$ make package
/index

Подключимся к роутеру по SSH. Включим наш репозиторий в /etc/opkg.conf. Установим MJPEG-Streamer:

$ opkg update
$ opkg install mjpg
-streamer

Настройки пакета находятся в файле /etc/config/mjpg-streamer. Отредактируем нужные строки:

config mjpg-streamer core
option device
"/dev/video0"
option resolution
"640x480"
option fps
"1"
option port
"310"
option enabled
"true"

Если камера отдаёт поток в формате MJPG, на этом настройка закончена. Моя камера отдаёт несжатый поток в формате YUV, для неё нужно включить JPEG-сжатие. Отредактируем файл /etc/init.d/mjpg-streamer. Найдём командную строку запуска демона:

$PROG ----input "input_uvc.so --device $device --fps $fps --resolution $resolution"--output "output_http.so --port $port"&

Добавим параметр –yuv для плагина input_uvc:

$PROG ----input "input_uvc.so --device $device --fps $fps --resolution $resolution --yuv"--output "output_http.so --port $port"&

Стартуем демон:

$ /etc/init.d/mjpg-streamer start

Если всё прошло нормально, должен включиться светодиод на камере. Для проверки работы сервера зайдём на 192.168.0.1:310/?action=stream. Не все браузеры нормально поддерживают MJPG-поток. Статическая картинка доступна по адресу 192.168.0.1:310/?action=snapshot. Для отображения видео на веб-странице можно использовать встроенную поддержку браузера (имеется в Firefox, Chrome, частично в Opera), Javascript или Java-апплет. Страничка с примерами есть дистрибутиве MJPEG-Streamer.

Индикация посетителей

Платка

Мне хотелось сделать какую-нибудь индикацию приходящих посетителей. Для этого я взял яркий RGB светодиод, подключил его к USB через самодельный переходник на микроконтроллере. Программу для управления написал и отладил в Visual C, затем портировал и собрал под роутер с помощью Buildroot’а OpenWrt. Приходящие посетители, активность веб-сервера и FTP и другие события обозначаются вспышками разных цветов. Впрочем, эта система заслуживает отдельного поста.

Регистрация домена

Я зарегистировал домен для своего проекта в зоне RU у 2domains.ru меньше чем за 100 рублей. Регистратор мне понравился, на верификацию ушло всего 4 часа.

P.S. На всякий случай

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

Вскрытие и перепрошивка роутера лишают тебя гарантии на девайс. Возможны и другие проблемы. Впрочем новые роутеры (например, DIR-320) сложно убить перепрошивкой — загрузчик зашит в энергонезависимую память микроконтроллера (в отличии, например, от RedBoot, использовавшегося в более ранних моделях), так что в любой момент можно сделать откат на оригинальную прошивку. Но в любом случае, ты ковыряешь роутер на свой страх и риск.

Удачи!

Добавить комментарий

Войти с помощью: