Open-source project
nikkinikki-org/OpenWrt-momo avatar
nikkinikki-org/OpenWrt-momo

Momo: a transparent proxy package for OpenWrt on top of sing-box

Transparent Proxy with sing-box on OpenWrt.

835 stars86 forksShellGPL-3.0

At a glance

What is it?
Momo is a GPL-3.0 licensed OpenWrt package, written mostly in shell, that runs sing-box as a transparent proxy on a router, with redirect, TPROXY and TUN interception, access control, a profile editor and a scheduled restart. It suits an OpenWrt user who wants a router level proxy managed from LuCI, and it is a poor fit if you want per device policy on a network you do not own.
Who is it for?
Momo suits an OpenWrt user who wants their own router to proxy traffic through sing-box with the whole thing managed from the LuCI interface, since the package handles the routing rules, the firewall rules and the restart schedule that a hand written setup usually gets wrong.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A proxy that owns the router's traffic path

Momo is a transparent proxy with sing-box on OpenWrt, and the repository description is one line: Transparent Proxy with sing-box on OpenWrt.

The word transparent is the whole idea. A conventional proxy is something you configure in a browser or an application, and every device on the network has to be told about it. A transparent proxy intercepts traffic at the router, so a phone that knows nothing about proxies still has its traffic proxied, and a device that has its own proxy configuration still cannot opt out without being noticed.

That is what the package is for, and it explains why it is a router package rather than a command line tool. The traffic has to pass through something the router controls, and OpenWrt is the natural place for that.

The implementation is mostly shell, with the repository containing feed.sh, install.sh, uninstall.sh, a luci-app-momo directory for the LuCI interface and a momo directory for the package itself, alongside the English and Chinese READMEs. The project is GPL-3.0 licensed, its homepage is momomomo.pages.dev, the last push to the repository was on 2026-10-14, and the recent releases are v1.2.2 on 2026-10-14, v1.2.1 on 2026-06-03 and v1.2.0 on 2026-04-10.

The audience is therefore an OpenWrt user with a router they control, who wants traffic to be proxied without configuring each client. Usage detail is in the project wiki, and the README points there rather than duplicating it.

Three prerequisites, and firewall4 is the one that catches people

The prerequisites section is three lines, and they are hard floors rather than suggestions.

OpenWrt 24.10 or later, a Linux kernel of 5.13 or later, and firewall4.

The firewall4 line is the significant one. OpenWrt moved from the older firewall3 to the newer nftables based firewall4 as the default in the 24.10 release, and this package is built against firewall4 with the nftables kernel modules it needs. A router still on the older stack, or one that has been kept on an older release, will not satisfy the requirement, and the package will not do anything useful there.

The kernel version matters for the same reason. The TPROXY interception mode in particular depends on kernel support, and the dependency list includes kmod-nft-tproxy and kmod-nft-socket, which are the modules that provide the transparent proxy and socket matching primitives in the firewall.

The dependency list in full is worth reading, because it explains what the package touches on your system.

code
ca-bundle
curl
firewall4
ip-full
kmod-inet-diag
kmod-nft-socket
kmod-nft-tproxy
kmod-tun
sing-box >= 1.12

Nine entries, and four of them are kernel modules. ip-full gives the policy routing commands the setup needs, kmod-inet-diag supports the socket diagnostics, and kmod-tun covers the TUN mode. The sing-box requirement of 1.12 or later is the other floor, and it is where the actual proxy engine comes from: Momo does not implement a proxy protocol, it configures and supervises sing-box.

Redirect, TPROXY and TUN, over IPv4 and IPv6

The feature list names the interception modes in one line: Transparent Proxy, with Redirect, TPROXY and TUN, over IPv4 and or IPv6.

Three mechanisms, and the difference between them is the substance of the whole package.

Redirect is the simplest. Traffic is rewritten to a local port and the proxy answers it, which works for TCP and is the easiest to set up, but the original destination address is lost or has to be passed out of band, and UDP handling is awkward.

TPROXY preserves the original destination address in the socket, which is what you need for transparent UDP and for protocols that care about the destination. It needs the kmod-nft-tproxy and kmod-nft-socket modules, which is why they are in the dependency list.

TUN is a different approach again. Instead of working with the firewall's packet path, a virtual network interface is created and the routing table sends traffic into it, with sing-box reading and writing packets at that interface. It needs kmod-tun. The TUN approach tends to be the most general, and also the most invasive, since it changes routing rather than adding rules to a chain.

The IPv4 and IPv6 statement means the package can handle dual stack networks, and given that a router with TPROXY on both families is a common configuration in the territories this project comes from, that is a deliberate piece of coverage rather than an afterthought.

Alongside the interception itself, the feature list has three more entries that are about operating the thing: access control, a profile editor, and a scheduled restart. Those three are what turn a set of scripts into something a household can live with.

Installing means piping a script into ash

There are two documented install routes, and both of them end the same way, with a shell script downloaded and run.

The recommended route is the feed. The first step adds the feed, and it only needs to be run once.

shell
# only needs to be run once
wget -O - https://github.com/nikkinikki-org/OpenWrt-momo/raw/refs/heads/main/feed.sh | ash

Then the packages are installed, either from a shell or from the Software menu in LuCI, and the README gives both the opkg and the apk forms since OpenWrt 24.10 ships with apk.

shell
# you can install from shell or `Software` menu in LuCI
# for opkg
opkg install momo
opkg install luci-app-momo
opkg install luci-i18n-momo-zh-cn
# for apk
apk add momo
apk add luci-app-momo
apk add luci-i18n-momo-zh-cn

Three packages, and the third is the Simplified Chinese translation of the interface, which is a detail that says something about the audience.

The alternative route installs from a release, again as a piped script.

shell
wget -O - https://github.com/nikkinikki-org/OpenWrt-momo/raw/refs/heads/main/install.sh | ash

And removal follows the same pattern, with an uninstall script.

shell
wget -O - https://github.com/nikkinikki-org/OpenWrt-momo/raw/refs/heads/main/uninstall.sh | ash

The pattern is worth pausing on. Piping a remote script straight into the shell is convenient and it is how a lot of router software is installed, but it also means the script runs with root on the machine that carries your traffic, and you are trusting the GitHub raw content at that moment. The feed route is the more conservative of the two, because after the feed is added the packages come through the normal package manager with its own integrity checks, and the LuCI Software menu is the path most people should take. The direct install script is the one to read before running.

Five steps from a profile to working routing

The how does it work section is a numbered list, and it reads more like a design note than a tutorial.

The steps are: run sing-box; set a scheduled restart; get the necessary parameters from the profile; set the ip rule and route; generate the firewall and apply it. The README then notes that the steps above may change based on the config.

The order tells you how the system fits together. The first two steps are about the proxy process itself, and the third is about the subscription, since the parameters come from a profile rather than from local configuration. The fourth step is the policy routing, where the ip rule and route entries decide which traffic is diverted into the proxy and which is not, and the fifth is the firewall, which is where the redirection rules are actually enforced.

That last point is the one to understand. A transparent proxy on a router is fundamentally a firewall rule that redirects packets to a local port. Getting the routing right without the firewall rule means the traffic never reaches sing-box, and getting the firewall right without the routing means the proxy sees traffic it should not. The package generates and applies the firewall configuration as part of its own flow, which is the part that would otherwise be a day of nftables work.

The scheduled restart is listed as a step rather than a feature because it is part of the flow. Running sing-box as a supervised service that is restarted on a schedule is a common way to keep a proxy working when the upstream configuration changes, and it is also the reason the package manages the process rather than leaving it to the init system alone.

The remaining two features, access control and the profile editor, are the ones that make the setup maintainable after the first hour. Access control decides which devices or which destinations are proxied, and the profile editor is where the subscription parameters are entered and changed.

Building from source means adding a feed to the OpenWrt build

For anyone who wants to build the package themselves rather than install a binary, the README gives the OpenWrt feed workflow.

shell
# add feed
echo "src-git momo https://github.com/nikkinikki-org/OpenWrt-momo.git;main" >> "feeds.conf.default"
# update & install feeds
./scripts/feeds update -a
./scripts/feeds install -a
# make package
make package/luci-app-momo/compile

The three steps are the standard OpenWrt package development path. The feed is declared against the main branch, the feeds scripts pull and check it out, and the package is compiled through the normal make target, which means the result goes through the same build system as every other package in the distribution.

The output lands in the usual place.

shell
The package files will be found under `bin/packages/your_architecture/momo`.

That path is worth noting, because the architecture component is the one thing you have to get right. The package depends on kernel modules, so a package built for one architecture is not usable on another, and a build for the wrong target is one of the more common ways to end up with a package that installs and then does not work.

The reason to build rather than install is usually a fork, a local change, or a specific architecture that the prebuilt release does not cover. There is a separate wiki and a Telegram channel linked from the README, and the repository also has a contributors graphic, so this is a community project with people who will answer questions.

Editorial conclusion

Momo suits an OpenWrt user who wants their own router to proxy traffic through sing-box with the whole thing managed from the LuCI interface, since the package handles the routing rules, the firewall rules and the restart schedule that a hand written setup usually gets wrong. It does not suit a network you do not administer, because the whole model is that the router owns the traffic path, and it does not suit a user who is unwilling to read the wiki, since the README is a summary and the wiki holds the usage detail. Before you install it, check the three prerequisites, since OpenWrt 24.10 or later, a kernel of 5.13 or later and firewall4 are all required and the older firewall3 based systems will not work, confirm sing-box 1.12 or later is available on your feed, and note that the installation is a shell script piped into ash, so read the feed script before running it on a router that carries your traffic.

Frequently asked questions

What is Momo on OpenWrt?

Momo is a transparent proxy package for OpenWrt built on sing-box, with redirect, TPROXY and TUN interception over IPv4 and IPv6, plus access control, a profile editor and a scheduled restart. The project is GPL-3.0 licensed and mostly shell.

What are the prerequisites for Momo?

The README lists OpenWrt 24.10 or later, a Linux kernel of 5.13 or later, and firewall4. The dependency list also requires sing-box 1.12 or later, curl, ca-bundle, ip-full and the kmod-inet-diag, kmod-nft-socket, kmod-nft-tproxy and kmod-tun kernel modules.

How do I install Momo on OpenWrt?

The recommended route is to add the feed with feed.sh piped into ash, then install the momo, luci-app-momo and luci-i18n-momo-zh-cn packages with opkg or apk, or from the Software menu in LuCI. An alternative install.sh script is also provided, and an uninstall.sh for removal.

What does the Momo setup actually do?

According to the README the sequence is: run sing-box, set a scheduled restart, get the necessary parameters from the profile, set the ip rule and route, then generate the firewall and apply it. The README notes that these steps may change based on the configuration.

How do I build the Momo package from source?

Add the feed to feeds.conf.default, run the feeds update and install scripts, then run make package/luci-app-momo/compile. The built package files end up under bin/packages/your_architecture/momo, so the architecture has to match the target router.

Official sources

  1. License: GPL-3.0
  2. nikkinikki-org/OpenWrt-momo on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nikkinikki-org-openwrt-momo.svg)](https://hysenlabs.com/projects/nikkinikki-org-openwrt-momo)

Was this useful?