W jednym z artykułów -
sieć gościnna omówiłem sposób utworzenia dodatkowej sieci WLAN dla gości, tymczasowo chcących podłączyć się do naszej sieci. Jest to jedno z rozwiązań - inne, znaczne prostsze to udostępnienie interfejsu sieciowego bez żadnego szyfrowania - czyli stworzenie otwartej sieci, która działa jako hostspot. Takie rozwiązanie jest przyjazne dla użytkownika, ale warto było by zainteresować się także możliwością reklamy naszej sieci czy po prostu przywitania użytkownika. Powinno mieć to duże znaczenie przy zastosowaniu takiego rozwiązania komercyjnie np. w hotelach, choć w małej prywatnej sieci też może znaleźć zastosowanie np. do wysyłania informacji użytkownikowi.
Omówmy najpierw zasadę działania takiego projektu. Użytkownik widzi dostępną sieć publiczną (lub zna hasło do podłączenia się do niej). Loguje się, i przy próbie wywołania jakiejkolwiek strony pojawia mu się nasza strona informacyjna. Zmuszony jest potwierdzić chęć skorzystania z internetu i od tej pory ma całkowicie otwarty dostęp. Po pewnym czasie możemy usuwać reguły zezwalające i tym samym wymusić kolejne wyświetlenie strony użytkownikowi.
Realizacja tego zagadnienia jest stosunkowo prosta: tworzymy własny serwer www ze stroną informacyjną. Cały ruch przy pomocy odpowiednich reguł iptables należy przekierować na naszą stronę. Jeżeli użytkownik potwierdzi chęć skorzystania z internetu - odpowiednim skryptem zezwalamy na transmisję.
Do realizacji można użyć dowolnego routera z zainstalowanym serwerem www. Może to być czyste OpenWrt lub projekt Gargoyle - ważne aby pamiętać o uruchomieniu wbudowanego panelu zarządzenia (o ile jest zainstalowany) na innym porcie niż domyślny 80, który zostanie wykorzystany w tym przykładzie. Po szczegóły odsyłam do dokumentacji poszczególnych projektów.
Zaczynamy realizację projektu od zainstalowania serwera www (o ile go jeszcze nie ma). W tym przypadku będzie to
uhttpd:
opkg update
opkg install uhttpd
Następnie należy utworzyć konfigurację naszego serwera:
uci set uhttpd.hotspot=uhttpd
uci set uhttpd.hotspot.listen_http=0.0.0.0:80
uci set uhttpd.hotspot.home=/hotspot
uci set uhttpd.hotspot.interpreter=.cgi=/bin/ash
uci set uhttpd.hotspot.cgi_prefix=/cgi-bin
uci set uhttpd.hotspot.no_dirlists=1
uci commit uhttpd
/etc/init.d/uhttpd enable
I znów ta sama uwaga - zauważcie, że użyty tu został port 80, więc jeżeli są też inne sekcje konfiguracyjne to należy się upewnić, że nie nasłuchują one na porcie 80.
Katalog w którym zostanie umieszczona nasza strona powitalna został określony na
/hostspot; tworzy więc go:
mkdir /hotspot
a następnie umieszczamy w nim plik
index.html o następującej zawartości (to właśnie on decyduje o wyglądzie naszej strony powitalnej):
<html>
<head>
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="post-check=0, pre-check=0" />
<meta http-equiv="Pragma" content="no-cache" />
</head>
<body>
<center>
<h1>Witaj gościu!</h1>
Aby kontynuować, naciśnij OK
<form name="input" action="/cgi-bin/allow.cgi" method="post">
<input type="submit" value="OK" />
</form>
</center>
</body>
</html>
Strona jest prosta - wyświetla komunikat powitalny i przycisk "OK", po jego naciśnięciu zostanie wykonany skrypt
cgi-bin/allow.cgi, który zezwoli na skorzystanie z internetu. Tworzymy więc taki skrypt:
mkdir /hotspot/cgi-bin
touch /hotspot/cgi-bin/allow.cgi
chmod 755 /hotspot/cgi-bin/allow.cgi
a następnie umieszczamy w nim następujący kod:
#!/bin/sh
echo "Content-type: text/html"
echo ""
IP=$(env | awk -F= '/REMOTE_ADDR/ {print $2}')
iptables -t nat -D prerouting_blokada -p tcp -s $IP -j ACCEPT || true
iptables -t nat -I prerouting_blokada -p tcp -s $IP -j ACCEPT
cat << _EOF_
<html>
<head>
<meta HTTP-EQUIV="REFRESH" content="0; url=http://openrouter.info">
</head>
</html>
_EOF_
Kilka słów wytłumaczenia. Zadaniem skryptu jest uzyskanie ze zmiennych środowiskowych przekazanych z serwera www adresu IP klienta który wywołał stronę (czyli kliknął przycisk "OK") i zezwolenie na transmisję z tego adresu IP. Warto zauważyć, że manipulujemy łańcuchem "prerouting_blokada", który uprości późniejsze zarządzanie wpisami.
Strona jest już kompletna został tylko najważniejszy element - przekierowanie całego ruchu na nasz serwer. Wykonujemy to odpowiednim poleceniem
iptables. Całość wzbogacona jest wcześniejszym utworzeniem osobnego łańcucha, co pozwala na szybkie usunięcie wszystkich wpisów bez modyfikacji całego firewalla. Gotowy skrypt może wyglądać następująco (do umieszczenia w pliku
/etc/firewall.user)
iptables -t nat -F prerouting_blokada 2>/dev/null || ( \
iptables -t nat -N prerouting_blokada; \
iptables -t nat -I PREROUTING -i br-lan -j prerouting_blokada; \
)
IP=$(uci get network.lan.ipaddr)
iptables -t nat -A prerouting_blokada ! -d $IP/32 -p tcp -j DNAT --to $IP:80
I to wszystko. Po restarcie routera, cały ruch zostaje przekierowany na naszą stronę powitalną. Po wyświetleniu zawartości strony użytkownik potwierdza komunikat, a to powoduje wpisane odpowiedniej reguły iptables, zezwolenie na ruch i natychmiastowe przekierowanie na stronę startową, openrouter.info w tym przypadku.
Skrypt jest bardzo prosty i umożliwia dalszą modyfikację. Można pokusić się o jego rozbudowę o jeden z wymienionych elementów:
- logowanie użytkowników. W otwartej sieci może mieć znaczenie logowanie IP, MAC adresu i daty przyłączenia użytkownika
- ograniczenie dostępu tylko do określonych protokołów, np http i https
- wprowadzenie kontroli pasma, czyli przydzielenie użytkownikowi określonego poziomu transferu np. na poziomie 1Mbps
- wprowadzenie możliwości "aktywacji" dostępu do internetu przez system haseł wpisywanych przez użytkowników. Mogą to być hasła jednorazowe, co wiąże się z kolejnym pomysłem jakim jest
- wprowadzenie czasowego obowiązywania dostępu do internetu. Do realizowania przy pomocy crona i iptables, można usuwać reguły po upływie określonego czasu. Można także uzależnić dostęp godzinny, 4 godzinny itd od odpowiednich typów kodów
- lepsza integracja przekierowania - dodanie obsługi nieistniejących linków, strony błędy, przekierowania nieistniejących domen itd.
Możliwości rozbudowy jest wiele, ale związane to jest z potrzebą określonego zastosowania.
Należy pamiętać, że w repozytorium pakietów znajdziemy wiele gotowych projektów realizujących funkcjonalność hotspota tzw "Captive Portals" - z tych bardziej znanych warto wymienić chociaż by chilispot, choova-chilli czy nodogsplash. Jednakże polecam czasami także samodzielną realizację projektów, zwłaszcza jeżeli ma to być przeznaczone do realizacji konkretnego zadania.