Установка программного обеспечения из исходников под МГТС роутер ZTE F-660 в chroot окружении

от автора


Привет всем! Во многом благодаря компании МГТС и ее оптической сети GPON, я познакомился с оптическим модемом-роутером ZTE f-660. Как только дома появился этот девайс, у меня сразу появилась мысль поставить туда какую-нибудь прошивку с софтом вроде dd-wrt или open-wrt.

При внешнем осмотре у роутера был обнаружен usb порт.
В голову пришли следующие способы применения роутера в бытовых целях:

  1. SipProxy server;
  2. Torrent client;
  3. Ftp-сервер;
  4. Dlna-сервер;
  5. Примитивный веб-хостинг.

Поиск в интернете ничего не дал. На различного рода форумах, идет в основном обсуждение как на стену вешать или как порты открыть, более того я даже не нашел “стоковой" прошивки для него. Но на роутер есть телнет доступ (root root). Начав изучать внутренности прошивки я понял, что не все так просто. Текущая прошивка намертво привязана к телефонии и оптическому модему, и сменив ее, я по всей видимости, лишусь и телефона и интернета в лучшем случае, а в худшем просто «окирпичу» роутер без возможности восстановления. К тому же это может привести к штрафным санкциям от МГТС за замену роутера в размере ~1500р.
Единственный в вариант который мне виделся на тот момет, это запуск нужных мне программ в chroot окружении с флешки отформатированной в ntfs. Естественно мне хотелось использовать самые последние версии программ. Поэтому я решил собрать все из исходников.
Изучив аппаратную базу, я определил, что там стоит обычный mips-процессор работающий под линуксом 2.6.30. Соответственно нам необходимо собрать gcc-тулчан под данную архитектуру. Для сборки тулчана я выбрал обычную убунту.
Перед установкой нам необходимо поставить средства разработки

sudo apt-get install gcc g++ make grep gawk automake 

Скрипт я приведу ниже, а тут я опишу общий план и то на что необходимо обратить особое внимание
Не нужны никакие патчи;
./make-mips-toolchan <полный путь создаваемого toolchan> ;
Для того что бы скачать все исходники используйте параметр get;
Не используйте опцию -j > 1, не соберется получите кучу недетерминированных ошибок (Под убунту и gcc 4.8.1);
CLFS=“$1” дирректория в которую мы поместим тулчан. SYSROOT=“$CLFS/root”, дирректория в которую будут устанавливатся результат работы тулчана;
Если с первого раза не соберется, комментируете в скрипте уже пройденные этапы и продолжаете дальше;
В скрипт вторым параметром передается путь по которому необходимо разместить тулчан;
Этапы установки такие:

  • Ставим исходники ядра 2.6.30;
  • Ставим утилиты для работы с бинарными файлами (линковщик) binutils;
  • Ставим mips крос-компилятор gcc (без поддержки потоков);
  • С его помощью собираем стандартную библиотеку С (eglibc);
  • С помощью стандартной библиотеки собранной в предыдущем пункте соберем полноценный с++ тулчан;

#!/bin/sh TARGET="mips-unknown-linux-gnu" CLFS="$1" SYSROOT="$CLFS/root" HOST="x86_64-pc-linux-gnu" LINUX_VERSION=2.6.30 BINUTILS_VERSION=2.24 GCC_VERSION=4.8.2 EGLIB_VERSION=2.18-r24148 unset CFLAGS unset CXXFLAGS check_success() {    if [ $? -ne 0 ]    then       echo Failed       exit 1    fi    echo Done } if [ "$2" = "get" ] then echo -n "Download sources..." wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-$LINUX_VERSION.tar.bz2 wget http://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz wget http://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.bz2 wget http://cross-lfs.org/files/eglibc-$EGLIB_VERSION.tar.xz echo -n "Extract archives..." tar -xjf linux-$LINUX_VERSION.tar.bz2 tar -xf binutils-$BINUTILS_VERSION.tar.gz tar -xjf gcc-$GCC_VERSION.tar.bz2 tar -xf eglibc-$EGLIB_VERSION.tar.xz cd ./gcc-$GCC_VERSION/ ./contrib/download_prerequisites cd .. check_success fi if [ "$2" = "clear" ] then rm -rfv $CLFS mkdir -p $SYSROOT check_success exit 1 fi mkdir -p $SYSROOT    InstallKernelHeader() { echo -n "Install kernel headers..." cd linux-$LINUX_VERSION/ make mrproper make ARCH=mips headers_check make ARCH=mips INSTALL_HDR_PATH=$SYSROOT/usr headers_install cd .. check_success }  InstallBinutils() { echo -n "Install binutils..." mkdir mips-binutils cd mips-binutils rm -rf ./* ../binutils-$BINUTILS_VERSION/configure --prefix=$CLFS --target=$TARGET --with-sysroot=$SYSROOT  --disable-nls --disable-static --disable-multilib --enable-plugins make check_success make install check_success cd ..  }  InstallStaticGCC() { echo -n "Install static gcc..." mkdir mips-static-gcc cd mips-static-gcc rm -rf ./* ../gcc-$GCC_VERSION/configure --target=$TARGET --prefix=$CLFS --with-sysroot=$SYSROOT --disable-nls  --disable-shared --without-headers --with-newlib --disable-decimal-float --disable-libgomp --disable-libmudflap --disable-libssp --disable-threads --disable-multilib --disable-libatomic --disable-libitm --disable-libsanitizer --disable-libquadmath --disable-target-libiberty --enable-languages=c --enable-checking=release make all-gcc check_success make all-target-libgcc check_success make install-gcc install-target-libgcc check_success cd .. }   InstallEGLIB() { echo -n "Install eglibs header files..." mkdir mips-eglibs cd mips-eglibs rm -rf ./* BUILD_CC="gcc" \ CC="$CLFS/bin/$TARGET-gcc" \ AR="$CLFS/bin/$TARGET-ar" \ RANLIB="$CLFS/bin/$TARGET-ranlib" \ ../eglibc/libc/configure \ --prefix=/usr \ --with-headers=$SYSROOT/usr/include \ --build=$HOST \ --host=$TARGET \ --disable-profile --without-gd --without-cvs --enable-add-ons  check_success make check_success make install install_root=$SYSROOT check_success cd ..  } InstallFinallGCC() { echo -n "Install final gcc..." mkdir mips-final-gcc cd mips-final-gcc rm -rf ./* ../gcc-4.8.2/configure --prefix=$CLFS \ --build=$HOST --target=$TARGET --host=$HOST \ --with-sysroot=$SYSROOT --enable-shared --disable-static --enable-languages=c,c++ \ --with-libs=$SYSROOT/lib \ --enable-__cxa_atexit --enable-c99 --enable-long-long --enable-threads=posix \ --disable-multilib \ --enable-checking=release \ --disable-nls \ --enable-libstdcxx-time make  AS_FOR_TARGET="$CLFS/bin/$TARGET-as" LD_FOR_TARGET="$CLFS/bin/$TARGET-ld" -j 4 check_success make install check_success cp $CLFS/mips-unknown-linux-gnu/lib/libgcc_s.so $SYSROOT/usr/lib cd $SYSROOT/usr/lib ln -s ./libgcc_s.so ./libgcc_s.so.1 cd - cd .. }  InstallKernelHeader InstallBinutils InstallStaticGCC InstallEGLIB InstallFinallGCC 

С этого момента у вас есть полноценный gcc-тулчан который способен собирать программы под наш роутер. Для этого нам этапе конфигурирования программ нам необходимо указывать компилятор и линковщик из только что скомпилированного тулчана:

unset CFLAGS unset CXXFLAGS export LD="mips-unknown-linux-gnu-ld" export CC="mips-unknown-linux-gnu-gcc" export AR="mips-unknown-linux-gnu-gcc-ar" export RANLIB="mips-unknown-linux-gnu-ranlib" export STRIP=“mips-unknown-linux-gnu-strip” 

Все инструменты готовы и мы можем приступать к сборке программ.
В качестве примера соберем торрент клиент Transsmission и сип-прокси Sipproxd. Общий план такой:

  1. Сборка статически слинкованного bash интерпетатора;
  2. Сборка сетевых утилит GnuInetCoreUtills;
  3. Сборка основных утилит GnuCoreUtills;
  4. Сборка библиотеки текстового интерфейса NCurses (Нужна для Nano);
  5. Сборка консольного блокнота необходимого для редактирования файлов конфигурации Nano;
  6. Сборка библиотеки сжатия Zlib;
  7. Сборка криптографической библиотеки openssl;
  8. Сборка сетевой библиотеки Curl (Нужна для transsmission);
  9. Сборка библиотеки событий LibEvent (Нужна для transsmission);
  10. Сборка торрент клиента Transsmission;
  11. Сборка библиотеки GnuSip;
  12. Сборка SipProxy.

В процессе сборки пришлось применить ряд патчей все они очень простые добавляют или удаляют не больше одной строчки.

Сам скрипт:

#!/bin/bash check_success() {    if [ $? -ne 0 ]    then       echo Failed       exit 1    fi    echo Done } if [ "$2" = "get" ] then echo -n "Download sources..." wget "http://ftp.gnu.org/gnu/coreutils/coreutils-8.22.tar.xz" wget "http://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz" wget "http://www.openssl.org/source/openssl-1.0.1e.tar.gz" wget "http://zlib.net/zlib-1.2.8.tar.gz" wget "http://mirror.yandex.ru/pub/OpenBSD/OpenSSH/portable/openssh-6.4p1.tar.gz" wget "http://curl.haxx.se/download/curl-7.34.0.tar.gz" wget "http://download.transmissionbt.com/files/transmission-2.82.tar.xz" wget "http://ftp.gnu.org/gnu/inetutils/inetutils-1.9.2.tar.gz" wget "http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz" wget "http://www.nano-editor.org/dist/v2.2/nano-2.2.6.tar.gz" wget "https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz" wget "http://siproxd.tuxworld.ch/siproxd-01Feb2014.tar.gz" wget "http://ftp.gnu.org/gnu/osip/libosip2-4.1.0.tar.gz"   echo -n "Extract archives..." tar -xf zlib-1.2.8.tar.gz && rm zlib-1.2.8.tar.gz* tar -xf openssl-1.0.1e.tar.gz && rm openssl-1.0.1e.tar.gz* tar -Jxf coreutils-8.22.tar.xz && rm coreutils-8.22.tar.xz* tar -xf bash-4.2.tar.gz && rm bash-4.2.tar.gz* tar -xf openssh-6.4p1.tar.gz && rm openssh-6.4p1.tar.gz* tar -xf curl-7.34.0.tar.gz && rm curl-7.34.0.tar.gz* tar -xf transmission-2.82.tar.xz && rm transmission-2.82.tar.xz* tar -xf inetutils-1.9.2.tar.gz && rm inetutils-1.9.2.tar.gz* tar -xf ncurses-5.9.tar.gz && rm ncurses-5.9.tar.gz* tar -xf nano-2.2.6.tar.gz && rm nano-2.2.6.tar.gz* tar -xf libevent-2.0.21-stable.tar.gz && rm libevent-2.0.21-stable.tar.gz* tar -xf siproxd-01Feb2014.tar.gz && rm siproxd-21Jan2014.tar.gz* tar -xf libosip2-4.1.0.tar.gz && rm libosip2-4.1.0.tar.gz* check_success fi   InstallCoreUtils() { cd coreutils-8.22 make clean ./configure --prefix=/ --host=$HOST patch Makefile < ../dummymake.patch patch ./man/dummy-man < ../dummyman.patch make -j 4 make install DESTDIR=$SYSROOT cd ..  }   InstallBash() { cd bash-4.2 make clean ./configure --without-bash-malloc --prefix=/ --host=$HOST #--enable-static-link patch execute_cmd.c <  ../bashjobcontrol.patch make -j 4 check_success make install DESTDIR=$SYSROOT check_success cd .. }  InstallInetUtils() { cd inetutils-1.9.2 make clean ./configure --prefix=/usr --host=$HOST patch ./ifconfig/system/linux.c < ../inetutilpathprocspath.patch make -j 4 check_success make install DESTDIR=$SYSROOT check_success cd .. }  InstallZlib() { cd zlib-1.2.8 make clean ./configure --prefix=/usr make  -j 4 check_success make install DESTDIR=$SYSROOT check_success cd .. }  InstallOpenSSl() { cd openssl-1.0.1e make clean ./Configure linux-elf --prefix=/usr  no-asm -fPIC make check_success make install INSTALL_PREFIX=$SYSROOT check_success cd .. }  InstallOpenSSH() { cd openssh-6.4p1 make clean ./configure --prefix=/usr --host=$HOST --sysconfdir=/etc/ssh make LDFLAGS="-dynamic-linker /lib/ld.so.1 $SYSROOT/usr/lib/crt1.o $SYSROOT/usr/lib/crti.o $SYSROOT/usr/lib/crtn.o -L. -Lopenbsd-compat/ -L$SYSROOT/lib -lc -lgcc_s"  CFLAGS="-DHAVE_SETLOGIN -UHAVE_PROC_PID -fPIC -g -O2 -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -fno-builtin-memset -fstack-protector-all" -j 3 check_success  -j 4 make DESTDIR=$SYSROOT STRIP_OPT="--strip-program=mips-unknown-linux-gnu-strip" install-nokeys check_success cd .. }   InstallCurl() { cd curl-7.34.0 make clean ./configure --prefix=/usr --host=$HOST make check_success make install DESTDIR=$SYSROOT check_success cd .. } InstallLibEvent() { cd libevent-2.0.21-stable make clean ./configure --prefix=/usr --host=$HOST make -j 4 check_success make install DESTDIR=$SYSROOT check_success cd .. }  InstallTransmission() { cd transmission-2.82 make clean with_ssl=$SYSROOT/usr CFLAGS="-w" \ LIBEVENT_CFLAGS="-I$SYSROOT/usr/include/curl" LIBEVENT_LIBS="-L$SYSROOT/usr/lib/ -levent" \ LIBCURL_CFLAGS="-I$SYSROOT/usr/include/event2" LIBCURL_LIBS="-L$SYSROOT/usr/lib/ -lcurl" \ LDFLAGS="-L$SYSROOT/usr/lib/ -lssl -ldl" \ ./configure --prefix=/usr --host=$HOST --disable-gtk --disable-cli --disable-libnotify --disable-nls --disable-mac --disable-wx --disable-beos make -j 4 check_success make install DESTDIR=$SYSROOT check_success cd .. }  InstallNcurses() { cd ncurses-5.9 make clean ./configure --prefix=/usr --host=$HOST make check_success make install DESTDIR=$SYSROOT check_success cd .. }  InstallNano() { cd nano-2.2.6 mkdir buidnano cd buidnano rm -rfv ./* make clean ../configure --prefix=/usr --host=$HOST CFLAGS="-I$SYSROOT/usr/include/ncurses" make -j 4 check_success make install DESTDIR=$SYSROOT check_success cd ../.. }  InstallLibSip() { cd libosip2-4.1.0 make clean ./configure --prefix=/usr --host=$HOST make -j 4 check_success make install DESTDIR=$SYSROOT check_success cd .. }  InstallSipProxd() { cd siproxd-0.8.2dev make clean  ./configure --prefix=/usr --host=$HOST --with-libosip-prefix=$SYSROOT/usr replacestr=$SYSROOT/usr/lib sed -i -e 's|/usr/lib|'$replacestr'|g' $SYSROOT/usr/lib/libosipparser2.la sed -i -e 's|/usr/lib|'$replacestr'|g' $SYSROOT/usr/lib/libosip2.la patch ./src/dejitter.c < ../siproxytime.patch make -j 4 check_success make install DESTDIR=$SYSROOT check_success cd .. }       CLFS="$1" SYSROOT="$CLFS/root" HOST="mips-unknown-linux-gnu" export PATH=$CLFS/bin/:$PATH unset CFLAGS unset CXXFLAGS  export LD="mips-unknown-linux-gnu-ld" export CC="mips-unknown-linux-gnu-gcc" export AR="mips-unknown-linux-gnu-gcc-ar" export RANLIB="mips-unknown-linux-gnu-ranlib" export STRIP="mips-unknown-linux-gnu-strip"  InstallBash InstallInetUtils InstallCoreUtils  InstallNcurses InstallNano  InstallZlib InstallOpenSSl #InstallOpenSSH  InstallCurl InstallLibEvent InstallTransmission  InstallLibSip InstallSipProxd 

Далее на необходимо перенести нашу папку root которая находится в директории нашего тулчана на заранее отформатированную в nfts флешку. Также на флешку необходимо поместить статически слинкованный busybox готовый можно взять отсюда: www.busybox.net/downloads/binaries/latest/busybox-mips.
Далее нам нужно «запрыгнуть» в нашу песочницу, выполнив небольшой скрипт:

#!/bin/ash  export TERMINFO=/usr/share/terminfo export HOME=/root cp -rf /etc/* /mnt/usb1_1/root/etc  mkdir -p /mnt/usb1_1/root/root mkdir -p /mnt/usb1_1/root/dev mkdir -p /mnt/usb1_1/root/proc mkdir -p /mnt/usb1_1/root/sys mkdir -p /mnt/usb1_1/root/dev/pts  mount -o bind /dev /mnt/usb1_1/root/dev mount -o bind /proc /mnt/usb1_1/root/proc mount -o bind /sys /mnt/usb1_1/root/sys mount -o bind /dev/pts /mnt/usb1_1/root/dev/pts  ./busybox-mips chroot /mnt/usb1_1/root/ /bin/bash  

Мы увидим командную строку интерпретатора bash. Выполним настройку динамических библиотек командой ldconfig -v
С этого момента мы можем делать все что угодно так как мы отделены от основной системы.
Запустим торрент-клиент transmission-daemon. Перейдите по адресу 192.168.1.1:9091. Видим стандартный ответ на неавторизированный доступ

Далее необходимо отредактировать файл настроек (он только что был создан)

nano /root/.config/transmission-daemon/settings.json 

Замените настройки
«rpc-whitelist»: “127.0.0.1”
На
«rpc-whitelist»: “*.*.*.*”

Нажмите F2 что бы сохранить и выйти
Перезапустите демон. Зайдите по тому же адресу.

Далее я сделаю небольшой отступ и расскажу про Sip-Proxy и систему которая как я понимаю теперь применяется в МГТС. Сейчас МГТС практически полностью отказывается от аналоговой связи. Все звонки идут по сип-протоколу, те фактически наш роутер является по сути обычным сип-клиентом. Следовательно мы можем использовать любой сип-телефон и подключатся к сип-серверу и звонить с московского номера куда угодно. Звучит заманчиво, но есть одна проблема. Дело в том что мы не можем подключится к сип-серверу так как мы находимся за натом (вот в этом суждении я не претендую на объективность просто одна из версий). В качестве решения мы можем использовать сип-прокси. Он будет заниматься передачей пакетов от клиентов до сервера делая вид что он и есть клиент, как собственно и делает обычный http-прокси.
Внесем некоторые изменения в конфигурационный файл.
cd /usr/etc/
cp ./siproxd.conf.example ./siproxd.conf
nano ./siproxd.conf
Внесем следующие изменнения:
if_inbound  = br0
if_outbound = nbif1
daemonize = 0
 outbound_proxy_host = 192.168.68.97
 outbound_proxy_port = 5060
F2-сохраним
Запустим сам прокси-сервер в режиме логирования
siproxd -d -1 0
Зайдем и настройки сип-клиента в самом роутере и укажем что прокси теперь является он сам. После нажатия на кнопку применить мы видим как логах идут пакеты от нашего клиента.

00:16:23 accessctl.c:99 access check =3
00:16:23 security.c:48 security_check_raw: size=440
00:16:23 siproxd.c:481 checking Max-Forwards (=70)
00:16:23 siproxd.c:526 received SIP type REQ:REGISTER
00:16:23 utils.c:129 DNS lookup — previous resolution failed: msk.ims.mgts.ru

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

Подведем итог: как видим нам удалось собрать из исходников достаточно большое количество программного обеспечения. Особенно хотелось бы отметить что все собранное программное обеспечение свежее, нам не пришлось ни прошивать устройство ни использовать какой либо древний репозиторий. При этом мы воспользовались очень простыми патчами. Если заметка вызовет достаточным интерес в хабра-сообществе и мне удастся решить проблему сип-прокси, то я в следующей своей заметки могу рассмотреть вопросы связанные установкой на многостродальный роутер openssh, softether VPN и вопросы запуска x11 приложений. Вообще мне бы хотелось получить обратную связь и возможно появятся другие статьи на данную тему от других авторов, ведь данный терминал очень распространен в Москве.

Скрипты и патчи лежат в архиве.

ссылка на оригинал статьи http://habrahabr.ru/post/211759/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *