Alright, you made it this far—so let’s turn this thing up to 11.
If you’ve been playing along at home, you now have a fully functional MX150 running on NFX250 hardware. But there’s just one little problem: licensing.
Juniper, in all their wisdom, has decided that certain features should be paywalled behind license checks. Bandwidth limits, subscriber scaling, and BNG functionality are all locked behind a paywall that—let’s be honest—is more about squeezing MSPs than any real technical limitation.
Even just running up a stock-standard DHCP server? Nope. Not going to happen.
So, let’s fix that.
Diving Into the Licensing System
After running a few binaries through Ghidra, I stumbled across an interesting function buried deep in the codebase:
void license_is_nextgen_infra_active(void)
int iVar1; uint uVar2;
stat asStack_eb [2];
if (DAT_00f745b0 == Oxffffffff) {
iVar1 = stat("/config/license/conf/licinfra_nextgen.conf", asStack_e0);
if (iVar1 == 0) {
DAT_00f745b0 = 1;
} else {
iVar1 = stat("/config/license/conf/licinfra_legacy.conf", asStack_e0);
if (iVar1 == 0) {
DAT_00f745b0 = 0;
} else {
uVar2 = license_is_current_product_nextgenO;
DAT_00f745b0 = uVar2 & Oxff;
}
}
}
return;
Reading between the lines, this function determines whether the router operates in “nextgen” mode (enforcing modern licensing and feature restrictions) or “legacy” mode (which, interestingly, allows for older-style licensing with far fewer restrictions).
If we can trick the box into thinking it should be running in legacy mode, then we might just be able to bypass all of the modern limitations.
Flipping the Switch
It turns out, the check is dead simple to fool. The router simply looks for the presence of /config/license/conf/licinfra_legacy.conf
. If this file exists, the system assumes it should run in legacy mode.
In a root shell,
mkdir -p /config/license/conf/
touch /config/license/conf/licinfra_legacy.conf
chflags schg /config/license/conf/licinfra_legacy.conf
rm -rf /var/run/license_shmem
Why Use chflags
?
Because Junos tries to delete the file on boot. If /config/license/conf/licinfra_legacy.conf
exists, it gets removed before the system completes startup, forcing Agile Licensing mode back on. By setting the file as immutable using chflags schg
, the deletion fails, and the router boots into legacy mode instead. Nice security feature, right? 😂
Once rebooted, the box will accept legacy license keys (aka, the old ones floating around the internet) for the MX5, MX80, MX204 etc, which can be used to lift artificial bandwidth and scaling limitations, and unlock subscriber/BNG functionality that’s normally locked behind an expensive license.
Here’s the kicker—once in legacy mode, old MX5/MX80 keys that have been floating around for years just work. These licenses aren’t tied to Agile Licensing, meaning they’ll activate the relevant features without phoning home. No license server, no nonsense, just a fully unlocked router.
Wait, This Works on vMX Too?
Oh yeah. This doesn’t just work on the MX150/NFX250 – it works on vMX running on literally any commodity hardware. Fire up a vMX instance in KVM, drop the same legacy mode trick in place, and congrats, you now have an unrestricted Juniper router for your lab (or, you know, your “My First ISP” setup).
The Downsides? Not Much.
The only real downside? Running show system license
just returns nothing. The router doesn’t think it has any licenses installed, but all the features still work as expected. I haven’t bothered digging into whether that can be fixed, but honestly, who cares? This setup has been running flawlessly since March 8th, 2023—over two years and counting.
How Would Juniper Fix This?
If Juniper actually wanted to fix this and prevent the bypass, here’s how they could do it:
- Move Licensing Checks to Secure Storage
- Instead of relying on a simple file check, store the licensing state in a digitally signed and verified location, like TPM-backed secure storage or a signed certificate chain.
- Cryptographically Verify License Mode
- Instead of checking for the presence of a file, the system should validate a cryptographically signed token that authorizes legacy mode. If the token is missing or invalid, default to nextgen mode.
- Harden File System Integrity Checks
- Ensure that any critical licensing files are validated using checksum verification on boot.
- Block users from setting immutable flags (
chflags schg
) on critical files without proper authorization.
- Move Away from Static Config Checks
- Instead of checking for a static file in
/config/license/conf/
, make the license mode configurable only through an authenticated management API, ensuring it cannot be manipulated externally.
- Instead of checking for a static file in
A Note to Juniper: If you are reading this, send me an MX204, and I’ll stop picking on old hardware 😘
I’ll start picking on newer hardware instead 😉
I love your hardware, but let’s be real—charging thousands for software-enforced limits on a box that’s running on x86 is just begging people to find workarounds. Maybe rethink that whole licensing strategy, yeah? Oh, that’s right – you’ve killed vMX too. Boo.
Anyway, stay tuned for Chapter Three: The Ultimate Juniper BNG Setup. We’re just getting started. 🚀