Open-source project
nmatt0/mitmrouter avatar
nmatt0/mitmrouter

mitmrouter builds a Linux access point for capturing IoT traffic

Bash script to automate setup of Linux router useful for IoT device traffic analysis and SSL mitm

791 stars125 forksShellMIT

At a glance

What is it?
mitmrouter is a single Bash script that turns a Linux box into a routed access point with hostapd and dnsmasq, so IoT devices on the Wi-Fi network can be inspected and their TLS traffic redirected for interception. It suits hardware lab work, and it is a setup script rather than a proxy tool with its own inspection features.
Who is it for?
Adopt mitmrouter when you need a controlled access point on a Linux machine to capture traffic from IoT devices, and when you already know how to install a proxy CA certificate on those devices and how to configure the redirect rules in mitmrouter.conf. Do not adopt it as a general purpose interception proxy, because the script builds the network and the rules and leaves the inspection side to tools you supply.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 150 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

One script builds the router instead of you configuring it

mitmrouter is a Bash script that automates the setup of a Linux router, and the documentation is explicit about the purpose: it is useful for IoT device traffic analysis and SSL interception. The repository is small. The top level holds a LICENSE, a README, an img/ directory, a mitmrouter.conf.example file and mitmrouter.sh itself. That is the whole project. So the value is not in a codebase to study but in a working recipe for a specific network arrangement, which is a legitimately useful thing to have when the arrangement is fiddly. A capture setup usually involves a wired interface bridged to a wireless access point, a DHCP and DNS service for the clients, and firewall rules that decide which traffic is redirected. Doing that by hand on a fresh machine means reconciling hostapd, dnsmasq, bridge configuration and packet filtering, each with its own idea of what the interfaces should look like. The script exists to make that reproducible on a clean image.

The dependency list is short and each piece has one job

The stated dependencies are hostapd, dnsmasq, iproute2, which provides the ip command and is preinstalled on every modern Linux distribution, and nftables, which provides nft and is preinstalled on most modern Linux distributions. That is a deliberately minimal set with no Python runtime, no container runtime and no compiled component to install, which matters for the kind of machine this runs on, since a test rig or a spare laptop is often the environment. hostapd is what makes the wireless access point, dnsmasq handles address assignment and name resolution for the clients that join, iproute2 covers interface and route manipulation, and nftables is the packet filtering layer. Each dependency is used for a single well understood job, so when something fails you can test the layer without reading the script. The one mismatch worth noticing is between the dependency list and the usage text, since the refresh command is described as re-applying iptables rules even though the listed firewall dependency is nftables.

Configuration lives in a copy of the example file

Before the script runs, the documentation asks you to copy mitmrouter.conf.example to mitmrouter.conf and edit it with your interface names, Wi-Fi SSID, password and other details. The script is forgiving about the first run. If mitmrouter.conf is missing, the script auto-creates it from the example and exits, so that you have a file to edit rather than an error to decode. Two configuration switches control the shape of the network. LAN_ENABLED and WIFI_ENABLED both default to 1, and setting either to 0 limits the router to a Wi-Fi-only or a wired-only LAN. The script refuses to start if both are 0, since a router with neither a wired bridge nor an access point has nothing to route. The switching is also asymmetric in a useful way. When WIFI_ENABLED is 0, hostapd is not started and the WIFI_IFACE interface name is ignored, and the same applies to LAN_IFACE when LAN_ENABLED is 0. The interface names therefore stay in the config file even when a mode is switched off, which keeps a single config usable across different lab setups.

up, down and refresh are three different operations

The script takes one argument:

bash
./mitmrouter.sh <up|down|refresh>

The up command tears down all the Linux router components and then builds them back up again. The down command brings the components down and stops there. The third one is the interesting one. refresh regenerates the dnsmasq and hostapd configs from mitmrouter.conf and re-applies the firewall rules without tearing down or re-creating the bridge and the interfaces. The documentation gives the reason: it is useful when you edit mitmrouter.conf and want to apply changes, for example new MITM redirect rules, without rebuilding the router from scratch. There is one visible consequence to plan for. Wi-Fi clients will re-associate because hostapd restarts, while the bridge stays up. So a refresh is close to seamless for the network structure and visible to every wireless client as a brief disconnection. For a lab where devices reconnect automatically that is a convenience, and for a lab where a session matters, it is a cost to be aware of before you edit rules mid-experiment.

The script builds the network and leaves the interception to you

Here is the boundary of what this project does. It creates the router, the access point, the address and name services for the clients, and the redirect rules that send traffic somewhere else. What it does not do is sit in the path and show you what is happening. The documentation mentions the SSL interception use case and the ability to add new MITM redirect rules to mitmrouter.conf, but the repository contains no proxy, no certificate authority, no packet decoder and no inspection interface. You supply that side. The architectural picture in the img/ directory named arch.jpg is the overview of how the pieces relate. In practice the workflow is that the script puts the traffic where you want it, and a separate tool of your choosing, whether that is a debugging proxy, a protocol analyser or your own script, does the reading. That division is why the tool is small. The hard, repeatable part is the network plumbing, and that is what is packaged.

NetworkManager is the first thing to turn off

The usage section opens with a warning that is easy to skim past and expensive to ignore. You may want to disable NetworkManager, because it may fight for control of one or more of the network interfaces. That conflict is the classic failure mode for this kind of script. A service manager that manages interfaces will reassert its own configuration when it notices the addresses, routes or bridge membership changing, and it will do so asynchronously, usually at the least convenient moment. The symptom is a bridge that works for a minute and then goes back to a plain DHCP client, or a wireless interface that drops out of AP mode. Turning NetworkManager off for the interfaces the script uses removes that class of problem entirely. It is also a change to the host machine that has to be undone later, which is worth remembering on a laptop that also has to reach the internet while you work.

Maintenance state and what a fork inherits

The repository is not archived, and the last push was on 2026-05-26, which is a little under five months before October 2026. There are no GitHub releases, so there is no tag to pin a deployment to, and the version of what you are running is whatever the master branch held when you cloned it. The licence is MIT, which is the permissive case and the simplest one for a shell script you may need to edit. Because the script is short and the configuration is a single file, forking and adjusting is a realistic maintenance path rather than a last resort. The two things to expect over time are changes to the example config format, since the script regenerates the dnsmasq and hostapd configs from mitmrouter.conf and will expect a matching example file, and changes to the firewall backend. The dependency list names nftables while the refresh description mentions iptables rules, so a fork that upgrades the script should check which firewall tool it actually invokes on the machine in front of it.

Editorial conclusion

Adopt mitmrouter when you need a controlled access point on a Linux machine to capture traffic from IoT devices, and when you already know how to install a proxy CA certificate on those devices and how to configure the redirect rules in mitmrouter.conf. Do not adopt it as a general purpose interception proxy, because the script builds the network and the rules and leaves the inspection side to tools you supply. Verify first that hostapd, dnsmasq, nftables and iproute2 are present, that your wireless adapter supports AP mode, and that NetworkManager is disabled so it does not fight the script for the interfaces.

Frequently asked questions

What does mitmrouter need installed before it runs?

The listed dependencies are hostapd, dnsmasq, iproute2, which provides the ip command, and nftables, which provides nft. iproute2 and nftables are preinstalled on modern Linux distributions in most cases, while hostapd and dnsmasq usually need to be installed from the system package manager.

How do I configure mitmrouter before the first run?

Copy mitmrouter.conf.example to mitmrouter.conf and edit the interface names, Wi-Fi SSID, password and other details. If the config file is missing on first run the script creates it from the example and exits so you can edit it.

What is the difference between up, down and refresh in mitmrouter?

up tears down all the router components and builds them back up, down brings the components down, and refresh regenerates the dnsmasq and hostapd configs from mitmrouter.conf and re-applies the rules without tearing down the bridge and interfaces. On refresh, Wi-Fi clients re-associate because hostapd restarts.

Can mitmrouter run as a wired-only or Wi-Fi-only setup?

Yes. LAN_ENABLED and WIFI_ENABLED both default to 1, and setting either to 0 leaves a wired-only or Wi-Fi-only LAN. The script refuses to start if both are 0, and the matching interface name is ignored when its mode is disabled.

Official sources

  1. Issues
  2. License: MIT
  3. nmatt0/mitmrouter on GitHub
  4. README
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/nmatt0-mitmrouter.svg)](https://hysenlabs.com/projects/nmatt0-mitmrouter)

Was this useful?