This guide walks through the process of compiling and deploying a statically linked OpenSSH server for a MIPS-based router using `musl-cross-make`. It includes all necessary dependencies and ends with running a working SSH server on the device.
🎯 Motivation
The primary goal of this setup is to enable SSH tunneling from the MIPS router to an AWS server. This allows secure remote access to the router, even when it is behind NAT or a restrictive firewall by creating a reverse SSH tunnel to a publicly accessible AWS instance. This can also be used to setup the router as a honeypot.
✅ Prerequisites
- Host OS: Linux (or WSL on Windows)
- Target: mipsel-linux-musl
- Toolchain: [`musl-cross-make`](https://github.com/richfelker/musl-cross-make)
- Router: Stock firmware with shell access (e.g., via Telnet or Web CLI)
- Filesystem: Writable directory (`/var/tmp` or similar)
- Access Method: SCP or TFTP
⚙️ Step 1: Setup the Cross-Compiler Toolchain
Clone and Build musl-cross-make
git clone https://github.com/richfelker/musl-cross-make
cd musl-cross-make
make -j$(nproc) TARGET=mipsel-linux-musl1
make -j$(nproc) install TARGET=mipsel-linux-musl1
Export Toolchain Environment
export PATH=/mnt/c/Users/.../musl-cross-make/output/bin:$PATH
export CC=mipsel-linux-musl-gcc
export CXX=mipsel-linux-musl-g++
export STRIP=mipsel-linux-musl-strip
export LD=mipsel-linux-musl-ld
export AR=mipsel-linux-musl-ar
export RANLIB=mipsel-linux-musl-ranlib
export PKG_CONFIG_PATH=/mnt/.../musl-cross-make/output/mipsel-linux-musl/lib/pkgconfig
📦 Step 2: Build Required Libraries
🧩 Build `zlib` (Compression Support)
wget http://www.zlib.net/zlib-1.3.1.tar.gz
tar -xvf zlib-1.3.1.tar.gz && cd zlib-1.3.1
make clean
CC=$CC CFLAGS="-static -fno-PIC" ./configure --static --prefix=$PWD/../install
make -j$(nproc)
make install
Verify: libz.a should exist in the install path.
🔐 Build OpenSSL (Encryption)
wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz
tar -xvf openssl-1.1.1w.tar.gz && cd openssl-1.1.1w
make clean
CC=$CC CFLAGS="-static -fno-PIC" ./Configure --static linux-mips32 no-shared --prefix=$PWD/../install
make -j$(nproc)
make install
Verify: Look for libssl.a and libcrypto.a
🖥️ Build ncurses (Terminal Handling)
wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.2.tar.gz
tar -xvf ncurses-6.2.tar.gz && cd ncurses-6.2
make clean
CC=$CC ./configure --host=mipsel-linux-musl \
--prefix=$PWD/../install \
--enable-static --disable-shared \
--without-cxx-binding --without-ada --without-progs \
--without-tests --without-debug \
--without-manpages --without-trace \
LDFLAGS="-static" CFLAGS="-static -fno-PIC"
make -j$(nproc)
make install
Verify: Check for libncurses.a
🔧 Step 3: Configure & Compile OpenSSH
cd rht/openssh-8.8p1
make clean
export LIBS="-static"
./configure --host=mipsel-linux-musl \
--prefix=/mnt/c/Users/jackady/Documents/clones/musl-cross-make/output/mipsel-linux-musl \
--disable-strip --disable-pam \
--with-zlib=/mnt/c/Users/jackady/Documents/clones/musl-cross-make/output/mipsel-linux-musl \
--with-ssl-dir=/mnt/c/Users/jackady/Documents/clones/musl-cross-make/output/mipsel-linux-musl \
--with-curses=/mnt/c/Users/jackady/Documents/clones/musl-cross-make/output/mipsel-linux-musl \
LDFLAGS="-static -Wl,-Bsymbolic -Wl,--allow-multiple-definition -Wl,-z,notext -L$PKG_CONFIG_PATH/../lib" \
CFLAGS="-static -I$PKG_CONFIG_PATH/../include"
make -j$(nproc)
make install
🚚 Step 4: Transfer to Router
Use scp or tftp to copy binaries to the router:
scp output/mipsel-linux-musl/bin/sshd admin@192.168.0.1:/var/tmp/
scp output/mipsel-linux-musl/bin/ssh admin@192.168.0.1:/var/tmp/
scp output/mipsel-linux-musl/bin/scp admin@192.168.0.1:/var/tmp/
scp output/mipsel-linux-musl/bin/sftp admin@192.168.0.1:/var/tmp/
scp output/mipsel-linux-musl/bin/ssh-keygen admin@192.168.0.1:/var/tmp/
Or use `tftp` if SCP is not available.
🚀 Step 5: Start OpenSSH Server
/var/tmp/sshd -D -p 2222
Use `-D` to keep it in the foreground (useful for debugging).
🔌 Step 6: Test SSH Access
From a separate system:
ssh -p 2222 admin@192.168.0.1
You should be dropped into a shell. ✅
📋 Summary Table
| Step | Task | Command |
|------|------|---------|
| 1 | Toolchain Setup | `make -j$(nproc) TARGET=...` |
| 2 | Build zlib | `./configure && make` |
| 3 | Build OpenSSL | `./Configure && make` |
| 4 | Build ncurses | `./configure && make` |
| 5 | Configure OpenSSH | `./configure --host=...` |
| 6 | Compile OpenSSH | `make && make install` |
| 7 | Transfer to Router | `scp ...` |
| 8 | Run SSH Server | `sshd -D -p 2222` |
| 9 | Test Connection | `ssh -p 2222 admin@router` |
---
