Small business captive portal with php

Hello everyone,
I'd first would like to thank everyone that will take the time to read and answer my question.

I'm new to OpenWRT. I've installed it and messed with it quite a bit on a raspberry pi 4 4GB as a test before buying an appropriate router if I achieve my goals.

I'm stuck with a technical issue that has more to do with a global workflow question than a configuration issue.

I'm running a small business with paid clients and "free" clients. The paying ones get the wifi password that does not change. No issue here.

As for the "free" user, I need them to register for the day on a separate internet app. I then can test if they're they're correctly registered using a custom PHP script (running on a separate web server with css and a bit of JS) that sends an OK or KO after checking the user status. I can modify that PHP script to some extent if need be. (It uses Rest GET and POST to APIs).

The idea is to give access to internet only if they're registered. I also need a way to give them access to both the registering site and the web server with the script even if they're not currently registered.

I thought about a captive portal (tried opennds) but I was limited to the "no css nor JS limitation".
Giving them access to only 2 sites that uses PHP and a lot of JS even without passing the splash screen seems difficult and not designed for this use.

I thought also about creating 2 SSIDs. 1 limited to both IPs only (registering site and validation script). The script would then display ok OK the wifi key to the 2nd SSID that would have all access. The 2nd wifi key would be changed via a script everyday at midnight.

I'm looking for more straightforward options in any of you think of it.

Thanks again for the time and have great day.

PS: I'll probably need help after figuring this first part out in order to configure the damn thing :wink:

That is a limitation of the sign-on minibrowser that pops up on smartphone OS. If users dismiss that and open a regular web browser to sign on, then there's no limitation.

This is a "smart" limitation of Apple, only. Any CP (Captive Portal) has to live with it, incl. commercial ones. A CP is the best choice for your application, not to re-invent the wheel; "Coova-chilli" is the most advanced CP, however, needs almost black magic for correct config, which means, steep learning curve. I.g. requires radius, for auth, speed limits, volume limits etc.

Thanks to you all. Can coova-chili allow certain access while not logged in (including JavaScript and css) and full access when authenticated ?
If so, that means that I'll need 2 "profiles" in the auth server?
Do you know anyone who can help with this "black magic" thing ?

Should I open a new topic ?
Thanks everyone.

This limitation is introduced by Apple, for their devices "Minibrowser", processing the Login Page. Has nothing to do with the Captive Portal itself. So, in case, you do not like it: Complain to Apple to remove this f... limitation. This limit does not exist for google/Android based systems/browsers.
"An coova-chili allow certain access why not logged in" Yes. The so called "Walled Garden" defines hosts, which may be accessed without being authed.
Black magic is not for free.

I'll have a look into that.
I understand that doing things FOR me comes at a cost. I was just seeking people knowledgeable in this field I could ask questions to for general direction.

Although that is true for some vendor versions it is certainly not true for all Android implementations.

With no restriction, any captive portal could direct a client device to download executable code and run it - not good from a security point of view given that a captive portal is a "Man In the Middle" attack device, albeit a benign one you would hope. The upcoming RFC 8910/8908 standard has the potential to mitigate the problem entirely, but support for this is still very immature and takeup is going to take a while.

Yes it can, and so can openNDS, if necessary defining a "Walled Garden" if access is required to a list of different FQDN's rather than a single server for the login pages.

BUT downloading remote js or css will be blocked by the client device itself for security reasons (as already discussed).

Interesting. Can you provide detailed references ? (Vendor, software, version ...)

From my experimentation during early development of openNDS a few years ago, I found Samsung Android up to v7 did not block as it used the "default" browser for captive portal login (initially the Samsung browser, but whatever the user installed and set as default browser).
At that time, all Google devices did block (using a mobile version of Chrome).
There was a whole range of other vendor Android versions either blocking or not blocking.
Since then I suspect more and more implementations block, but I have not done any tests recently.

" BUT downloading remote js or css will be blocked by the client device itself for security reasons (as already discussed)."
Are you referring to any JS or to JS from 3rd party, only ?

Any js code.

Hello, that is a very interesting discussion, even though it doesn't help me at all. :wink:

How about the JS code that is written in the html file between <script><\script> tags (same question goes for css.
I guess you can write html with "style=" inside the tags. So embedded css should work.
Could anyone confirm ?

Anyhow. Thanks to you all for allowing me to learn this much !

Did you evaluate, whether RADIUS and personal accounts helps for your requirements?

e.g. use one free Wifi, which only allows access to the http registration server which manages the RADIUS accounts.

And a second Wifi with Enterprise WAP and personal account RADIUS auth? If someone has not paid, you would just temporarily disable the account until the next payment is made.

I guess the best solution would be to use coova-chili using the "green garden" with only 1 site access :

  • the site to register (pay)

And when you want to connect to another site, then you need to enter credentials. Those would then be sent to a Radius server that would check with a custom code (not a database) the status of the client.
Ok > allow full access
KO > redirect to registering site.

Now, I need to look into how to configure all this....

Local css is fine, and some embedded js will work but only the simplest and even then it depends on the client vendor implementation.

Sure, but that is also the default mode for openNDS with external forwarding authentiction service (FAS).
Which way you go is completely up to you.

Really, I tried opennds and didn't fully understood that I could achieve my goal this with FAS.
Would you have any link / tutorial to point me to ?
If it's in the documentation, I'll have to look into that;-)

The provided fas-aes-https.php script would give you a secure https "login page".
It provides a dynamic set of login pages to get the client credentials.
You would then write a simple extension in php to check if the client has paid, if they have, then allow access. If they have not, do not allow access, or even present them with a payment page using something like Paypal.
An extension like this can be done quite easily just in php, no radius or anything complicated.
A single FAS server can handle many openNDS instances, as openNDS sends a unique ID to FAS.
You can even allow unpaid users a grace period with restricted bandwidth if you want, all automatically enforced.

Nice !!!
I'll have a look into that. Thanks a lot.
I'll try to keep you posted on this as I might not be the only one to look for this kind of things.

I'll also try to tell you depending on devices which one allow js/ css and to which extent.

A great day to you all !