Installing software from sources under MGTS router ZTE F-660 in chroot environment

Hello everybody! Largely thanks to MGTS and its GPON optical network, I met with the ZTE f-660 optical modem router. As soon as this device appeared at home, I immediately had the thought of putting some firmware with software like dd-wrt or open-wrt there.
Upon external inspection, a usb port was detected on the router.
The following ways of using the router for domestic purposes came to mind:
- SipProxy server;
- Torrent client;
- FTP server
- Dlna server
- Primitive web hosting.
A search on the Internet yielded nothing. On various kinds of forums, the main discussion is how to hang on the wall or how to open ports, moreover I didn’t even find “stock” firmware for it. But there is telnet access (root root) on the router. Having started studying the firmware inside, I realized that not everything is so simple. The current firmware is tightly tied to telephony and an optical modem, and if I change it, I will probably lose both my phone and the Internet in the best case, and in the worst case, I will simply “brick up” the router without the possibility of recovery. lead to penalties from MGTS for replacing ro lost in the amount of ~ 1500r.
The only option that I saw at that moment was the launch of the programs I needed in a chroot environment from a flash drive formatted in ntfs. Naturally, I wanted to use the latest versions of programs. Therefore, I decided to collect all of the source code.
After examining the hardware base, I determined that there is a regular mips-processor running under Linux 2.6.30. Accordingly, we need to build a gcc tool for this architecture. To build the tulkan, I chose the usual ubuntu.
Before installation, we need to put development tools
sudo apt-get install gcc g++ make grep gawk automake
I will give the script below, and here I will describe the general plan and what you need to pay special attention to:
No patches are needed;
The call syntax is as follows ./make-mips-toolchan <full path of the created toolchan>;
In order to download all sources use the get parameter;
Do not use the -j> 1 option, you are not going to get a bunch of non-deterministic errors (Under ubuntu and gcc 4.8.1);
CLFS = “$ 1” directory in which we put the tulchan. SYSROOT = “$ CLFS / root”, the directory in which the result of the tool’s work will be installed;
If you don’t get it right the first time, comment on the steps you have already completed in the script and continue on;
The second parameter passes to the script the path along which it is necessary to place the tulchan;
Installation steps are as follows:
- We put the kernel sources 2.6.30;
- We put utilities for working with binary files (linker) binutils;
- We put mips the cross-compiler gcc (without thread support);
- Using it, we build the standard C library (eglibc);
- Using the standard library collected in the previous paragraph, we will assemble a full-fledged c ++ tulchan;
#!/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
From now on, you have a full gcc tool that is able to collect programs for our router. To do this, we need to specify the compiler and linker from the just compiled tooltip during the configuration of programs:
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”
All tools are ready and we can begin to build programs.
As an example, let's collect the Transsmission torrent client and the Sipproxd sip proxy. The general plan is as follows:
- Build a statically linked bash interpreter;
- Assembly of network utilities GnuInetCoreUtills;
- Assembly of the main utilities GnuCoreUtills;
- Assembly of the NCurses text interface library (Needed for Nano);
- Build console notepad required for editing Nano configuration files;
- Build the Zlib compression library;
- Assembly of cryptographic library openssl;
- Build the Curl network library (Needed for transsmission);
- Build the LibEvent event library (Needed for transsmission);
- Assembling the torrent client Transsmission;
- Build the GnuSip library;
- SipProxy assembly.
During the assembly process, I had to apply a number of patches; all of them are very simple, add or delete no more than one line.
The script itself:
#!/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
Next, you need to transfer our root folder, which is located in the directory of our toolkit, to a flash drive pre-formatted in nfts. Also on the USB flash drive you need to put the statically linked busybox ready, you can take it from here: www.busybox.net/downloads/binaries/latest/busybox-mips .
Next, we need to "jump" into our sandbox by running a small script:
#!/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
We will see the bash interpreter command line. Let's configure the dynamic libraries with the ldconfig -v command.
From now on, we can do anything we want since we are separate from the main system.
Run the torrent client transmission-daemon. Go to the address 192.168.1.1:9091. We see the standard response to unauthorized access.

Next, you need to edit the settings file (it has just been created)
nano /root/.config/transmission-daemon/settings.json
Replace settings
«rpc-whitelist»: "127.0.0.1 "
On
«rpc-whitelist»: ". .. * * * *"
Press F2 to save it and exit
Restart the daemon. Go to the same address.

Next, I will make a small digression and talk about Sip-Proxy and the system which, as I understand it, is now used in MGTS. Now MGTS almost completely refuses analogue communications. All calls go through the sip protocol, those in fact our router is essentially an ordinary sip client. Therefore, we can use any sip phone and connect to the sip server and call from a Moscow number from anywhere. It sounds tempting, but there is one problem. The fact is that we cannot connect to the sip server since we are behind the nat (in this proposition, I do not pretend to be objective, it’s just one of the versions). As a solution, we can use sip proxy. He will deal with the transfer of packets from clients to the server, pretending that he is the client, as a matter of fact, he does the usual http proxy.
We will make some changes to the configuration file.
cd / usr / etc /
cp ./siproxd.conf.example ./siproxd.conf
nano ./siproxd.conf
made the following izmenneniya:
if_inbound = br0
if_outbound = nbif1
daemonize = 0
outbound_proxy_host = 192.168.68.97
outbound_proxy_port = 5060
F2-save
Run the proxy server itself in logging mode
siproxd -d -1 0 Let's go in
and configure the sip client in the router itself and indicate that the proxy is now it itself. After clicking on the apply button, we see how the logs go packets from our client.

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
But for some reason the proxy is trying to get the server address, instead of just passing the packet on without change. To be honest, this is one of the reasons why I posted the article on Habr. I just don’t know how to solve this problem, and I hope that the habro-community will help to solve this problem.
To summarize: as we see, we managed to collect a fairly large amount of software from the source. I would especially like to note that all the collected software is fresh, we did not have to either flash the device or use any ancient repository. In doing so, we used very simple patches. If the note causes enough interest in the hubr community and I manage to solve the sip proxy problem, then in my next note I can consider issues related to installing openssh, softether VPN and issues of launching x11 applications on a multi-channel router. In general, I would like to receive feedback and maybe other articles on this topic from other authors will appear, because this terminal is very common in Moscow.
Scripts and patches are in the archive .
Update (Links fixed):
For the laziest archive from the root directory of the flash drive, with installed programs