It is possible, but not without great difficulty.
You need ipset
, and a scriptable web server.
First, you create an "IPset" to record the IP addresses of the computers that already saw the captive portal
ipset create AlreadySaw hash:ip timeout $timeout
Next, you create the set of rules.
The first rule captures traffic from hosts not inside the "AlreadySaw" IPset:
-t nat -A PREROUTING -m set ! --match-set AlreadySaw src -j REDIRECT
The second set of rules resets the timeout of packets passing through the gateway:
-A FORWARD -m state --state ESTABLISHED -j Estab
-A Estab -j SET --add-set AlreadySaw src --exist
-A Estab -j ACCEPT
Finally, create a webserver that listens on ports :80 and :443, which will present the user with a 'captive portal', and upon the user successfully doing something asked by the 'captive portal', will then execute the following command:
ipset add AlreadySaw %IP%
... where %IP% is the source IP Address, which should be detected by the 'captive portal''s script.
.
The difficult part, of course, is in making the 'captive portal''s script. That, I leave to you as homework :)