Tuesday, May 18, 2010

Captive Portal Engine

IPTABLES rule!
It is so simple that you can do it yourself.

First initialize the firewall in a custom file which can be called from /etc/init.d:

# Allow DHCP and DNS requests from any user:
iptables -t nat -A prerouting_rule -m state --state NEW,ESTABLISHED,RELATED,INVALID -p udp --dport 67 -j ACCEPT
iptables -t nat -A prerouting_rule -m state --state NEW,ESTABLISHED,RELATED,INVALID -p tcp --dport 67 -j ACCEPT
iptables -t nat -A prerouting_rule -m state --state NEW,ESTABLISHED,RELATED,INVALID -p udp --dport 53 -j ACCEPT
iptables -t nat -A prerouting_rule -m state --state NEW,ESTABLISHED,RELATED,INVALID -p tcp --dport 53 -j ACCEPT

# All other traffic goes to the portal page: 
iptables -t nat -A prerouting_rule -p tcp -j DNAT --to 10.0.0.1:80
iptables -t nat -A prerouting_rule -p udp -j DNAT --to 10.0.0.1:80

# Create a captive NET where approved users will go and we have full control of how they behave:
iptables -t nat -N NET
iptables -t nat -A PREROUTING -j NET
iptables -t nat -A NET -j ACCEPT

Done!

Now the controlling of NET access.

# Add a user with MAC address of 00:90:4B:B1:5A:75.
iptables -t nat -I prerouting_rule -m mac --mac-source 00:90:4B:B1:5A:75 -j NET

# Remove a user with MAC address of 00:90:4B:B1:5A:75.
iptables -t nat -D prerouting_rule -m mac --mac-source 00:90:4B:B1:5A:75 -j NET


# Add a website (e.g. www.google.com) to walled garden
iptables -t nat -I prerouting_rule -m state --state NEW,ESTABLISHED,RELATED,INVALID -d "www.google.com" -j ACCEPT

# Remove a website (e.g. www.google.com) from walled garden
iptables -t nat -D prerouting_rule -m state --state NEW,ESTABLISHED,RELATED,INVALID -d "www.google.com" -j ACCEPT

There ya go! That's how it works.

Of course, additional to the IPTABLEs rules, you need to devise a web interface which handles users' logins, registrations and tracks usage. Lighttpd is chosen as the web server because of its ability to re-write visitor's URL and force the visitor to visit the portal page instead.


6 comments:

  1. What is the reason you pass through port 67 and 53 TCP?
    And why do you redirect UDP/80 to captive portal? Thanks!

    ReplyDelete
  2. Port 67/53 are for DHCP and DNS requests. If disabled, people can't retrieve an IP address/resolve any hostnames. UDP80 is because some webservers use UDP too.

    ReplyDelete
  3. Well, you better exclude traffic to your router admin page and allow ssh logins ..

    ReplyDelete
  4. If i just want devices to have 100% internet access after passing through my landing page, do i need to create the NET at all? or do I just have to add something like .* to my walled garden?

    ReplyDelete
  5. @r_0_y

    I am afraid NET is the heart of the captive portal and cannot be done away. After the device's MAC address is approved by the portal, it enters the NET and the NET allows the device to go anywhere on the internet without any restriction.

    ReplyDelete
  6. Hello! I was wondering if I can add the user to the net zone by its Ip address instead of its MAC, as i'm planning to have some fixed IPs. How would be the iptables rule in that case?

    ReplyDelete