Skip to content

jery04/Captive-Portal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

18 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Captive Portal โ€” DNS & Firewall Controller ๐Ÿ›ก๏ธ๐Ÿ–งโš™๏ธ

Overview

This repository provides a compact, production-minded captive-portal controller that intercepts unauthenticated clients at the firewall and DNS layers and redirects them to a local web portal for authentication. It operates by applying iptables DNAT rules for HTTP/DNS and installing per-IP exceptions after successful authentication.

Why this project exists

  • Lightweight: minimal dependencies, focused on iptables/dnsmasq-based deployments.
  • Deterministic: per-IP firewall exceptions avoid stateful proxy complexity.
  • Portable: designed to run on Linux AP hosts (hostapd+dnsmasq) with Python 3.

Quick highlights

  • Primary techniques: iptables DNAT for HTTP/DNS, POSTROUTING MASQUERADE, per-IP FORWARD exceptions.
  • Components: main.py (controller), server.py (portal web server), firewall.py (rule manager), sessions.py (session store).

Files of interest

  • main.py โ€” controller entrypoint that applies rules and coordinates authentication.
  • server.py โ€” web portal (HTTP) that serves captive pages and authentication endpoints.
  • firewall.py โ€” helpers for manipulating iptables and DNAT rules.
  • sessions.json / sessions.py โ€” session storage and lookup.

Prerequisites & capabilities โš™๏ธ

  • Linux host with hostapd and dnsmasq (AP mode recommended).
  • Root privileges to manage interfaces and iptables (or carefully scoped sudoers).
  • Python 3.8+ (recommended). The service can run as an unprivileged user if bind capabilities are granted.

Security & permissions ๐Ÿงฐ

Limit the commands allowed via sudo to reduce risk. Example visudo line (replace your_user):

your_user ALL=(ALL) NOPASSWD: /usr/sbin/iptables, /sbin/sysctl, /usr/sbin/arp

If you need the portal to bind to privileged ports, grant the Python binary the capability instead of running as root:

sudo setcap 'cap_net_bind_service=+ep' $(which python3)
getcap $(which python3)
# Example output: /usr/bin/python3 = cap_net_bind_service+ep

Example network setup (Wiโ€‘Fi AP) ๐Ÿ“ก

This sequence shows a typical interface and service setup used for testing the portal:

sudo iw dev wlan0 interface add wlan1 type __ap
sudo nmcli dev set wlan1 managed no
sudo ip link set wlan1 up
sudo ip addr add 192.168.100.1/24 dev wlan1
sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo iptables -A FORWARD -i wlan1 -o wlan0 -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo systemctl start dnsmasq
sudo hostapd /etc/hostapd/hostapd.conf

Firewall & DNS behavior (how it works) ๐Ÿ”

  • Default policy: unauthenticated clients are blocked from forwarding to the WAN.
  • HTTP interception: DNAT TCP/80 -> portal_ip:8080 so HTTP requests land on the portal server.
  • DNS interception: DNAT UDP/TCP/53 -> portal_ip:53 so DNS queries resolve to the portal before auth.
  • NAT: POSTROUTING MASQUERADE is used for outbound traffic via the WAN.
  • Authentication flow: once a client authenticates, the controller inserts per-IP FORWARD and NAT exceptions that restore normal connectivity for that client.

dnsmasq recommendations ๐Ÿงญ

  • Keep dnsmasq as the DHCP server and let the firewall perform DNS interception for unauthenticated clients.
  • Optionally, to always return the portal IP for any DNS answer before authentication, use:
address=/#/<portal_ip>

but ensure authenticated clients receive valid upstream DNS servers via DHCP (dhcp-option=6,1.1.1.1,8.8.8.8).

Quick start โ–ถ๏ธ

  1. Configure your AP interface and start dnsmasq/hostapd (see example above).
  2. Start the portal controller from the repository root:
python3 main.py

Operational notes & troubleshooting ๐Ÿž

  • Replace interface names (wlan0, wlan1) with the host's actual device names.
  • Ensure IP forwarding is enabled: cat /proc/sys/net/ipv4/ip_forward should be 1.
  • If redirection fails, inspect NAT rules: sudo iptables -t nat -L -n -v and sudo iptables -S.
  • Confirm the portal is listening on the expected port: ss -ltnp | grep python.

Development & testing ๐Ÿ› ๏ธ

  • Create a virtualenv and install dependencies (if you add a requirements.txt):
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
  • Important files to inspect when modifying behavior: main.py, server.py, firewall.py, sessions.py.

Next steps / enhancements โœจ

  • Convert this Readme to README.md and add badges, quick-start scripts, and example configurations.
  • Add automated tests for iptables rule generation and session handling.

License & contact

See the repository license for usage and contribution rules. For questions or to request changes to this README, open an issue or contact the repository owner.

-- Updated: concise technical README with clear quick-start and troubleshooting guidance.

About

๐ŸŒ Captive Portal implementation for network access control. Blocks external traffic until user authentication via HTTP login. Built using standard libraries and OS CLI tools. Supports user accounts and concurrent sessions.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors