Proposal to implement a Reverse Portal
-
There has been a demand for something like a Reverse Portal on this forum and elsewhere on the internet for at least two decades. Here I propose an implementation and extend an offer to build it in exchange for a bounty.
Implementation
A basic statement of what it should do is simple enough:
- Setup UI to configure the following:
- Choose an interface to bind and serve web requests for the login page.
- What pass rule to apply when a user has authenticated from an IP.
- Run a web service with login and connected pages.
- When a user authenticates and loads the connected page, add the configured rule.
- When the user disconnects, remove the rule.
- To track disconnects precisely, require the user to keep the connected page open throughout the duration of their session with a live SSE connection to the web service & regular heartbeats; when the connection times out then the rule is removed.
- Ability to run multiple instances of the Reverse Portal, like Captive Portal "zones"
Note: Admins would be responsible for ensuring clients can access the web service before logging in, and for configuring the firewall to default-deny clients until the configured rule is added.
Implementation seems straightforward, if not simple. Here are some relevant resources:
- A related bounty was posted in 2008: Conditional Connection Daemon {Now $400}
- This is essentially how Captive Portal works; here is where it calls
/sbin/pfctl
with rule changes piped via stdin. - It may be a good idea to reuse the captive portal login page.
- See also: FreeBSD uses a ported version of OpenBSD PF firewall; OpenBSD PF docs; OpenBSD pfctl docs
- pfSense Docs: Developing Packages
- SSE (Server-Sent Events) with PHP and JS / Streaming with PHP
Bounty
I don't have funds to contribute to this proposal, but -- assuming the above implementation proposal is roughly feasible -- I think I could develop it in 30 hours at a rate of $100/hr; $3000 total. My qualifications, such as they are: this detailed proposal, polyglot senior software developer, familiar with web technology and firewall fundamentals, I have never developed against FreeBSD, with PHP, or used pfSense until recently. I believe my estimate is padded enough to account for learning the required technologies.
I would not be offended if someone more qualified swipes the bounty for less as long as I get to use it too.
Maybe this is more of a solicitation for bounties rather than an offer to pay a bounty... I hope that's allowed!
- Setup UI to configure the following:
-
Rereading this I realize I didn't provide much context or frame the issue very well, and since I can't edit I'll post what the OP should have started with here.
From the pfSense Docs:
Captive Portal in pfSense software forces users on an interface to authenticate before granting access to the Internet. Where possible, the firewall automatically presents a login web page in which the user must enter credentials such as a username/password, a voucher code, or a simple click-through agreement.
Users have made many requests for something similar, but for authorizing access into the intranet, instead of out to the internet. This is often called a "reverse portal". This would be useful for e.g. setting up MFA for wireguard vpn connections or requiring login to access a different segment of the local network. Unfortunately, despite being nearly identical in implementation, netgate explicitly states that their captive portal feature is not capable of acting as a reverse portal, aka authorizing access to the local intranet.
One of the challenges with reverse portals is how to know when the user has disconnected and needs to reauthenticate. Here I propose a design where the user has to keep a browser tab with an open tcp connection (SSE with heartbeats) connected to the firewall to for the pass rule to be enabled; when the connection closes the pass rule is disabled and they will have to reauthenticate.