Skip to content

Captive Portal med IPtables

En Captive Portal är en sorts gästportal som visar sig när du försöker ansluta till internet. De kan användas för att logga in, betala eller helt enkelt acceptera ett användaravtal.

Här tänkte jag demonstrera hur jag bygger en captive portal server med CentOS 7 och iptables.

Grundprincipen kan förklaras med följande steg.

  1. Ny användare ansluter till WiFi
  2. Ingen trafik tillåts ut på internet
  3. En portalsida måste besökas för att aktivera trafik ut på internet
  4. När aktivering är klar kan användaren bruka internet som vanligt
  5. Åtkomst till internet tas bort efter en viss tid

Förberedelse

Stäng av firewalld

sudo systemctl stop firewalld && sudo systemctl disable firewalld

Installera paket

sudo yum install -y conntrack-tools iptables iptables-services python-virtualenv

Aktivera iptables

sudo systemctl enable iptables && sudo systemctl start iptables

Aktivera routing

Så att paket routas mellan nätverkskorten.

sudo sysctl net.ipv4.ip_forward=1

Konfigurera iptables

Bästa platsen att ha iptables-regler är ''/etc/sysconfig/iptables'' eftersom de kan läsas in av systemctl när tjänsten startas om.

Reglerna fungerar ungefär så här:

  1. Skapar en ny chain med namn internet och placerar all inkommande trafik i den
  2. Lägger till undantag i internet som t.ex. tillåtna klienter eller DNS/NTP trafik
  3. Till sist märker man all trafik med ett tal (99), all trafik utom undantagen
  4. Senare i filter-tabellen spärrar man all trafik som är märkt med talet 99
  5. Bara undantagen kommer igenom eftersom de inte märktes
  6. Nya klienter läggs in i början av internet-kedjan med RETURN-target för att undantas från märkningen

Här är reglerna skrivna i samma format som verktygen iptables-save och iptables-restore använder, kommentarer på engelska.

Conntrack

Att bara skapa brandväggsregler som hoppar över markeringen av paket, som i steg 2 ovan, räcker inte. Linux brandväggar har conntracking som kan minnas anslutningar och skicka paket samma väg för att spara tid/resurser. Detta är nyttigt för t.ex. lastbalansering.

I en captive portal måste vi alltså rensa conntracking informationen efter att vi skapat brandväggsreglerna.

$ sudo conntrack -D --orig-src 10.4.5.6

Se mer exempel i github.

Konfigurera Dnsmasq

Servern behöver även Dnsmasq för att utlösa funktionen som finns i många mobila enheter att visa en portalsida innan internet börjar användas.

Denna funktion är baserad på att alla DNS-frågor går till en och samma IP-adress, i detta fallet ska det vara vår gateway-server.

interface={{input_nic}}

# Exceptions we want forwarded to upstream DNS

server=/ntp.org/8.8.4.4/8.8.8.8
server=/github.com/8.8.4.4/8.8.8.8
server=/centos.org/8.8.4.4/8.8.8.8
server=/fedoraproject.org/8.8.4.4/8.8.8.8

# Handles everything else

address=/#/{{webportal_ip}}

Fallgropar

I en testmiljö kanske du råkar ut för problem om du har två nätverkskort i samma subnät, se till att bara ett nätverkskort används som default route i ditt OS.

Ändra ''DEFROUTE=no'' i konfigurationen för kortet som du tänker ha på insidan, alltså kortet dina klienter ska ansluta mot.

Symptomen av detta är att du i tcpdump inte ser någon trafik på insidans kort när du trots allt routar trafik genom det till utsidan.

Se också


Last update: June 6, 2020