more docs and examples.

This commit is contained in:
Stefan Midjich 2016-12-13 15:33:20 +01:00
parent ea51951696
commit 5ece708067
5 changed files with 153 additions and 0 deletions

View file

@ -11,6 +11,10 @@ This is a commonly seen setup in public Wifi networks or hotspots.
This app was specifically written for such a hotspot and as such requires a lot of other configuration around it. This is an ongoing [documentation project here](https://wiki.sydit.se/teknik:guider:networking:captive_portal_med_iptables).
## More documentation
I've moved all examples from the [aforementioned wiki-page](https://wiki.sydit.se/teknik:guider:networking:captive_portal_med_iptables) to the docs/examples directory.
# Plugins
Plugins are executed when the user clicks through the captive portal form, whether they submit data or just approve an EULA these plugins are executed.

View file

@ -0,0 +1,9 @@
# IPtables example
The example is written for Ansible so it contains Jinja2 brackets for things like input NIC, output NIC and other items important for a captive portal firewall configuration.
Server configurations vary so it's not applicable to any situation but it might help as guidance and it's well commented.
# Script examples
They're also written as Ansible templates because I copy them straight from my Ansible playbooks for deploying the captive portal. But it matters less for them, no important values to keep track of, everything is argument input.

View file

@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Captiveportal iptables wrapper script
#iptables_mac = iptables -t mangle -I internet 1 -m mac --mac-source {mac_address} -j RETURN
# First argument must be IP-address of client
test -n "$1" || exit 1
client_ip="$1"
ipt=/sbin/iptables
# Enable client traffic in internet chain by jumping over the mark
$ipt -t mangle -I internet 1 -p tcp --source "$client_ip" -j RETURN &>/dev/null && \
$ipt -t mangle -I internet 1 -p udp --source "$client_ip" -j RETURN &>/dev/null
iptables_rc=$?
# Delete conntrack info for client IP
/usr/local/sbin/rmtrack.sh "$client_ip" &>/dev/null
rmtrack_rc=$?
if [[ $iptables_rc == 0 && $rmtrack_rc == 0 ]]; then
# Success
exit 0
else
echo "Error: iptables[$iptables_rc], rmtrack[$rmtrack_rc]" 1&>2
exit 1
fi

View file

@ -0,0 +1,98 @@
# {{ ansible_managed }}
#
# These rules are for the Captive Portal project.
# by Stefan Midjich - 2016/03
# Routing of traffic requires: sysctl net.ipv4.ip_forward = 1
#
# {{captiveportal_conf.input_nic}} is LAN and used as default route on LAN clients.
# {{captiveportal_conf.output_nic}} is WAN.
# {{captiveportal_conf.webportal_ip}} is the same as IP on {{captiveportal_conf.input_nic}}
# Mangle table allows the marking of traffic. If you use -j RETURN before
# -j MARK you jump out of the internet chain and your traffic is not marked.
*mangle
:PREROUTING ACCEPT
:INPUT ACCEPT
:OUTPUT ACCEPT
:POSTROUTING ACCEPT
# Create custom chain in mangle table called "internet"
:internet - [0:0]
# Run all traffic from {{captiveportal_conf.input_nic}} through the internet chain
-A PREROUTING -i {{captiveportal_conf.input_nic}} -j internet
# Example to allow authorized clients in by MAC address
#-A internet -m mac --mac-source "xx:xx:xx:xx:56:eb" -j RETURN
# Live example: -I internet 1 -m mac --mac-source "xx:xx:xx:xx:56:eb" -j RETURN
# inserts at the top of the rules before the mark rule.
#
# iptables -t mangle -I internet -m tcp -p tcp --source 1.2.3.4 -j RETURN
# iptables -t mangle -I internet -m udp -p udp --source 1.2.3.4 -j RETURN
# For MGMT SSH traffic return out of internet chain so it's not marked
-A internet -p tcp -d {{captiveportal_conf.webportal_ip}} --dport ssh -j RETURN
# Bypass NTP also
#-A internet -p udp --dport ntp -j RETURN
# Mark all other traffic in the internet chain with 99. Any traffic after
# this rule is marked and blocked.
-A internet -j MARK --set-mark 99
COMMIT
# NAT rules that redirect traffic and allow the portal server to act as gateway.
*nat
:PREROUTING ACCEPT
:INPUT ACCEPT
:OUTPUT ACCEPT
:POSTROUTING ACCEPT
# Redirect all marked HTTP traffic to the webportal IP
-A PREROUTING -m mark --mark 99 -p tcp --dport http -j DNAT --to-destination {{captiveportal_conf.webportal_ip}}
-A PREROUTING -m mark --mark 99 -p tcp --dport https -j DNAT --to-destination {{captiveportal_conf.webportal_ip}}
# Redirect all marked DNS traffic to the webportal IP
-A PREROUTING -m mark --mark 99 -p udp --dport domain -j DNAT --to-destination {{captiveportal_conf.webportal_ip}}
-A PREROUTING -m mark --mark 99 -p tcp --dport domain -j DNAT --to-destination {{captiveportal_conf.webportal_ip}}
# Redirect all ICMP to the webportal IP
-A PREROUTING -m mark --mark 99 -p icmp -j DNAT --to-destination {{captiveportal_conf.webportal_ip}}
# Redirect all unmarked DNS traffic to upstream DNS servers
{% for server in captiveportal_conf.upstream_dns %}
-A PREROUTING -p udp --dport domain -j DNAT --to-destination {{server}}
-A PREROUTING -p tcp --dport domain -j DNAT --to-destination {{server}}
{% endfor %}
# Route any traffic out through the output NIC to act as gateway
-A POSTROUTING -o {{captiveportal_conf.output_nic}} -j MASQUERADE
COMMIT
# Filter rules that determine access to the portal server.
*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT
# Enable stateful connections
-I OUTPUT -o {{captiveportal_conf.output_nic}} -d 0.0.0.0/0 -j ACCEPT
-I INPUT -i {{captiveportal_conf.input_nic}} -m state --state ESTABLISHED,RELATED -j ACCEPT
# Accept HTTP traffic both to the server and forwarded
-A INPUT -p tcp --dport http -j ACCEPT
-A FORWARD -p tcp --dport http -j ACCEPT
# Accept DNS traffic to self
-A INPUT -p udp --dport domain -j ACCEPT
-A INPUT -p tcp --dport domain -j ACCEPT
# Drop all other traffic marked 99
-A FORWARD -m mark --mark 99 -j DROP
-A INPUT -m mark --mark 99 -j DROP
COMMIT

View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Conntracking keeps track of active connections so even if a user
# authenticates with a captive portal and new firewall rules are
# created it will take a while before the client takes these new
# routes. So conntrack -D can expedite that process.
test -n "$1" || exit 1
client_ip=$1
conntrack_cmd=/sbin/conntrack
# Deletes all conntracking entries for connections originating from
# to webportal server IP so that hopefully new connections can be
# initiated directly to destination.
$conntrack_cmd -D --orig-src $client_ip --orig-dst {{captiveportal_conf.webportal_ip}}