net/natpmp-client: NAT-PMP client plugin for provider assigned inbound ports
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 1.2k
- Forks
- 863
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 10
Description
Important notices
Before you add a new report, we ask you kindly to acknowledge the following:
- I have read the contributing guide lines at https://github.com/opnsense/plugins/blob/master/CONTRIBUTING.md
- I have searched the existing issues, open and closed, and I'm convinced that mine is new.
- When the request is meant for an existing plugin, I've added its name to the title.
Is your feature request related to a problem? Please describe.
Commercial VPN providers that offer an inbound port hand it out over NAT-PMP, and they change it
without notice — ProtonVPN grants 60 second leases. OPNsense can answer NAT-PMP requests
(os-upnp) but has no way to make one, so there is no supported way to obtain such a port or to keep
a rule pointing at it. What people do instead is a cron job around natpmpc that rewrites a rule
and reloads the filter, which races the ruleset it is editing and leaves the port forwarded to a
lease nobody renewed once the script dies.
Describe the solution you'd like
A NAT-PMP client plugin: a small daemon that requests and renews leases toward a gateway, and a
firewall hook that publishes a destination NAT rule following whatever public port the gateway
currently grants. The rules come from the plugin system rather than from config.xml, so they are
regenerated on every filter reload and are withheld the moment the daemon stops renewing.
I have written it and have been running it. Working and tested against a live ProtonVPN endpoint:
lease request, renewal and expiry; the redirect following the public port; an optional inbound pass
rule, off by default, with reply-to so replies leave through the tunnel; both rules withheld when
the daemon is not running; reached end to end from the internet.
Describe alternatives you've considered
os-upnp— the server side of the same protocol, not a client, and not extendable into one.- A shell script on cron. It works until the port changes: it cannot hand the new port to the
ruleset without editing rules underneath a filter reload, and it has no way to take the redirect
down when it stops running. - Speaking NAT-PMP from the plugin instead of driving
natpmpc. Fewer moving parts, but it means
writing protocol code where a maintained library already exists.
Additional context
Before writing more, I would rather ask whether this is wanted at all, and settle three things the
guidelines raise:
- The binary is in FreeBSD ports but not in the OPNsense package set. The plugin drives
/usr/local/bin/natpmpcfromnet/libnatpmp(20250404). The port exists and the FreeBSD package
installs cleanly, butPLUGIN_DEPENDS=libnatpmpfails the build because OPNsense does not build
it. Would you consider adding it toopnsense/tools, or would you rather the plugin spoke the
protocol itself and carried no dependency? - Size. 22 files, about 2350 lines excluding licence headers — roughly 900 of Python for the
daemon, 250 of PHP for the firewall hook, the rest MVC model, controllers, forms and the page.
The guidelines say a large initial codebase cannot be reviewed. If this is over the line, I would
rather hear what to cut than submit it as it stands. - AI disclosure. Written and tested with Claude (Anthropic), model Opus 5. The design decisions,
the testing on real hardware and this request are mine.
One design point worth flagging, since it is the part that opens the firewall: the inbound pass rule
is a per-mapping option and is off by default. The redirect alone changes nothing about what is
allowed in; the operator has to ask for the opening, and it is scoped to the internal host and port
rather than to the rotating public one.
Branch, as a single commit:
https://github.com/l0rdg3x/opnsense-plugins/tree/natpmp-client
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Review the linked natpmp-client branch, starting with its Python daemon, PHP firewall hook, and MVC files, then check the CONTRIBUTING.md guidance. Confirm whether the libnatpmp dependency, 22-file scope, and firewall-rule behavior are acceptable; done requires maintainer agreement on those design and packaging questions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, python
- Domain
- networking, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100