Coova Chilli Hotspot/Installation
Inhaltsverzeichnis
Hauptseite
Zurück zur Einführung
Debian Lenny Installation
Zwar verwendet der Autor hier Debian Lenny, aber diese Anleitung sollte auch weitestgehend auf alle anderen Debian- basierten Distributionen übertragbar sein. Mit ein paar Modifikationen kann man sie sicher auch auf RedHat oder SuSE übertragen.
Basis Installation
Für die Installation reicht in der Regel die NetInst Installations CD Um flexibel zu bleiben, entscheide ich mich für eine LVM Konfiguration für die Partitionierung:
| Quelle | MountPoint | Größe | Dateisystem |
|---|---|---|---|
| /dev/sda1 | /boot | 150MB | ext3 |
| /dev/sda2 | SWAP | 512MB - 1GB | SwapFS |
| /dev/system/root_fs | / | 3-5GB | ext3 |
| /dev/system/tmp_fs | /tmp | 512MB | ext3 |
| /dev/system/var_log_fs | 2GB | /var/log | ext3 |
Weitere Pakete
Die Installation sollte selbst nur die absolute Basis sein. Es reicht daher in der Softwareauswahl entweder alles zu deaktivieren, oder einzig "Standard" aktiviert zu lassen. Ist die Installation soweit abgeschlossen und der Rootprompt bereit, werden nun einige Pakete nachinstalliert:
- Pakete nachinstallieren
spot01 ~ # apt-get install vim ssh nullmailer mysql-server |
Vim dient hier lediglich dazu, den Komfort zu erhöhen, beim editieren von Textdateien. Es kann stattdessen natürlich jeder andere Editor verwendet werden, wie z.B joe od. mc. Als absolutes Pflichtpaket gehört ein SSH Server auf den Rechner. Für den Fall der Fälle, dass E-Mail den Rechner verlassen sollen, wird der SMTP Server nullmailer verwendet. Er dient lediglich dazu, E-Mails an einen richtigen E-Mail Server weiterzuleiten. Der MySQL Server wird für die Authentifizierung und Session Verwaltung benötigt. Während der Installation wird nach einem Root Kennwort gefragt, welches entsprechend ausgefüllt werden sollte.
Netzwerk Konfiguration
Wir gehen hier davon aus, dass wir über zwei Netzwerkkarten verfügen:
- eth0 - über sie erreichen wir das Internet und wird per DHCP konfiguriert
- eth1 - an dieser Netzwerkkarte hängt der AccessPoint und/oder ein Switch für die W-Lan od. Kabel Clients
Während die eth0 ihre IP Adresse und Default Route über einen DHCP Server bezieht, wird die eth1 dagegen unkonfiguriert belassen. Sie wird später automatisch von Coova Chilli verwendet.
- /etc/network/interfaces
auto lo iface lo inet loopback # Externe NIC zum Router/Internet auto eth0 iface eth0 inet dhcp # NIC mit den W-LAN Clients auto eth1 |
FreeRadius Server
Wie bereits erwähnt, benötigen wir einen Authentifizierungsserver. Diese Funktion stellt uns der Service FreeRadius zur Verfügung. Als Datenquelle kann der Radius Server unterschiedliche Dienste abfragen. Darunter sind z.B. LDAP, SQL, oder die lokale /etc/passwd Datei. In diesem Fall verwenden wir den bereits installierten MySQL Server. Daher kommt noch das Modul für diesen dazu.
- FreeRadius installieren
spot01 ~ # apt-get install freeradius freeradius-mysql |
MySQL Datenbank
Datenbank anlegen
Als nächstes wird die Datenbank erstellt und mit Tabellen gefüllt:
- Datenbank erstellen
spot01 ~ # mysqladmin -psecret create radius spot01 ~ # mysql radius < /etc/freeradius/sql/mysql/schema.sql -psecret spot01 ~ # mysql radius < /etc/freeradius/sql/mysql/nas.sql -psecret |
Mit dem ersten Kommando erzeugen erzeugen wir die Datenbank. Das MySQL Root Kennwort (hier secret) wird der Bequemlichkeit- halber gleich mit gegeben. Das zweite und dritte Kommando füllt die Datenbank und legt die nötigen Tabellen an. Auch hier geben wir das Root Kennwort gleich mit.
Datenbank Benutzer
Da wir nicht den Root Account verwenden wollen, für den Zugriff auf die Datenbank, erzeugen wir einen Benutzer, der die dazu nötigen Rechte erhält. Am einfachsten ist es, eine Datei mit den entsprechenden Kommandos anzulegen und sie dann dem MySQL Server zuzuführen:
- radius-user.sql
CREATE USER 'radius'@'localhost';
SET PASSWORD FOR 'radius'@'localhost' = PASSWORD('radiuspass');
# The server can read any table in SQL
GRANT SELECT ON radius.* TO 'radius'@'localhost';
# The server can write to the accounting and post-auth logging table.
#
# i.e.
GRANT ALL on radius.radacct TO 'radius'@'localhost';
GRANT ALL on radius.radpostauth TO 'radius'@'localhost';
GRANT ALL on radius.radcheck TO 'radius'@'localhost';
GRANT ALL on radius.nas TO 'radius'@'localhost';
|
Es wird also ein Benutzer radius angelegt, mit dem Kennwort radiuspass. Er darf auf alle Tabellen lesend zugreifen und zusätzlich schreibend auf die Tabellen radacct, radpostauth, radcheck, nas. Dies jedoch nur vom eigenen Rechner. Nun fügen wir den Benutzer mit folgendem Befehl hinzu:
- Benutzer hinzufügen
spot01 ~ # mysql < radius-user.sql -psecret |
Ob dies geklappt hat, kann man überprüfen mit:
spot1:~# mysql -uradius -pradiuspass radius -e 'show tables;' +------------------+ | Tables_in_radius | +------------------+ | nas | | radacct | | radcheck | | radgroupcheck | | radgroupreply | | radpostauth | | radreply | | radusergroup | +------------------+ |
FreeRadius anpassen
Nun muss der FreeRadius Server darauf vorbereitet werden. Dazu bearbeiten wir zuerst die für MySQL zuständige Datei:
- /etc/freeradius/sql.conf
sql {
database = "mysql"
driver = "rlm_sql_${database}"
server = "localhost" # DB Server
login = "radius" # DB Benutzernamen
password = "radiuspass" # DB Passwort
radius_db = "radius"
acct_table1 = "radacct"
acct_table2 = "radacct"
postauth_table = "radpostauth"
authcheck_table = "radcheck"
authreply_table = "radreply"
groupcheck_table = "radgroupcheck"
groupreply_table = "radgroupreply"
usergroup_table = "radusergroup"
read_groups = no
deletestalesessions = yes
sqltrace = no
sqltracefile = ${logdir}/sqltrace.sql
num_sql_socks = 5
connect_failure_retry_delay = 60
readclients = yes # von No auf Yes
nas_table = "nas" #
$INCLUDE sql/${database}/dialup.conf # Einbinden
}
|
Da die Datei eine Menge Kommentare beinhaltet, wird sie hier Vollständigkeit abgebildet. Wirklich interessant sind allerdings nur die Zeilen für den MySQL Server, sowie die letzten drei Zeilen.
Nun muss diese Datei noch vom Radius Server eingebunden werden, welches wieder über ein Include geschieht. Dazu müssen wir nun die Hauptkonfiguration- Datei öffnen:
- /etc/freeradius/radiusd.conf
prefix = /usr
exec_prefix = /usr
sysconfdir = /etc
localstatedir = /var
sbindir = ${exec_prefix}/sbin
logdir = /var/log/freeradius
raddbdir = /etc/freeradius
radacctdir = ${logdir}/radacct
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/freeradius
db_dir = $(raddbdir)
libdir = /usr/lib/freeradius
pidfile = ${run_dir}/freeradius.pid
user = freerad
group = freerad
max_request_time = 30
cleanup_delay = 5
max_requests = 1024
listen {
type = auth
ipaddr = *
port = 0
}
listen {
ipaddr = *
port = 0
type = acct
}
hostname_lookups = no
allow_core_dumps = no
regular_expressions = yes
extended_expressions = yes
log {
destination = files
file = ${logdir}/radius.log
syslog_facility = daemon
stripped_names = no
auth = no
auth_badpass = no
auth_goodpass = no
}
checkrad = ${sbindir}/checkrad
security {
max_attributes = 200
reject_delay = 1
status_server = yes
}
### kann abgeschaltet werden ####
proxy_requests = no
##### #####
$INCLUDE proxy.conf
$INCLUDE clients.conf
snmp = no
$INCLUDE snmp.conf
thread pool {
start_servers = 5
max_servers = 32
min_spare_servers = 3
max_spare_servers = 10
max_requests_per_server = 0
}
modules {
pap {
auto_header = no
}
chap {
authtype = CHAP
}
pam {
pam_auth = radiusd
}
unix {
radwtmp = ${logdir}/radwtmp
}
$INCLUDE eap.conf
mschap {
}
ldap {
server = "ldap.your.domain"
basedn = "o=My Org,c=UA"
filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"
ldap_connections_number = 5
timeout = 4
timelimit = 3
net_timeout = 1
tls {
start_tls = no
}
dictionary_mapping = ${confdir}/ldap.attrmap
edir_account_policy_check = no
}
realm IPASS {
format = prefix
delimiter = "/"
}
realm suffix {
format = suffix
delimiter = "@"
}
realm realmpercent {
format = suffix
delimiter = "%"
}
realm ntdomain {
format = prefix
delimiter = "\\"
}
checkval {
item-name = Calling-Station-Id
check-name = Calling-Station-Id
data-type = string
}
preprocess {
huntgroups = ${confdir}/huntgroups
hints = ${confdir}/hints
with_ascend_hack = no
ascend_channels_per_line = 23
with_ntdomain_hack = no
with_specialix_jetstream_hack = no
with_cisco_vsa_hack = no
}
files {
usersfile = ${confdir}/users
acctusersfile = ${confdir}/acct_users
preproxy_usersfile = ${confdir}/preproxy_users
compat = no
}
detail {
detailfile = ${radacctdir}/%{Client-IP-Address}/detail-%Y%m%d
detailperm = 0600
header = "%t"
}
acct_unique {
key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port"
}
$INCLUDE sql.conf ###### Wichtiger Teil #######
radutmp {
filename = ${logdir}/radutmp
username = %{User-Name}
case_sensitive = yes
check_with_nas = yes
perm = 0600
callerid = "yes"
}
radutmp sradutmp {
filename = ${logdir}/sradutmp
perm = 0644
callerid = "no"
}
attr_filter attr_filter.post-proxy {
attrsfile = ${confdir}/attrs
}
attr_filter attr_filter.pre-proxy {
attrsfile = ${confdir}/attrs.pre-proxy
}
attr_filter attr_filter.access_reject {
key = %{User-Name}
attrsfile = ${confdir}/attrs.access_reject
}
attr_filter attr_filter.accounting_response {
key = %{User-Name}
attrsfile = ${confdir}/attrs.accounting_response
}
counter daily {
filename = ${db_dir}/db.daily
key = User-Name
count-attribute = Acct-Session-Time
reset = daily
counter-name = Daily-Session-Time
check-name = Max-Daily-Session
reply-name = Session-Timeout
allowed-servicetype = Framed-User
cache-size = 5000
}
always fail {
rcode = fail
}
always reject {
rcode = reject
}
always noop {
rcode = noop
}
always handled {
rcode = handled
}
always updated {
rcode = updated
}
always notfound {
rcode = notfound
}
always ok {
rcode = ok
simulcount = 0
mpp = no
}
expr {
}
digest {
}
expiration {
reply-message = "Password Has Expired\r\n"
}
logintime {
reply-message = "You are calling outside your allowed timespan\r\n"
minimum-timeout = 60
}
exec {
wait = yes
input_pairs = request
shell_escape = yes
output = none
}
exec echo {
wait = yes
program = "/bin/echo %{User-Name}"
input_pairs = request
output_pairs = reply
shell_escape = yes
}
# Kann unbeachtet bleiben, nur fuer Dial IN !!!
ippool main_pool {
range-start = 192.168.1.1
range-stop = 192.168.3.254
netmask = 255.255.255.0
cache-size = 800
session-db = ${db_dir}/db.ippool
ip-index = ${db_dir}/db.ipindex
override = no
maximum-timeout = 0
}
policy {
filename = ${confdir}/policy.txt
}
}
instantiate {
exec
expr
expiration
logintime
}
$INCLUDE policy.conf
#### Nebenconfig ####
$INCLUDE sites-enabled/
|
Auch hier die vollständige Datei. Zu beachten ist lediglich $INCLUDE sql.conf Zeile.
Da auch hier wiederum Teile ausgegliedert wurde, muss eine weitere Datei editiert werden. Ähnlich wie bei einem Apachen, können unterschiedliche Konfigurationen erzeugt werden, für unterschiedliche Zwecke. Diese liegen im /etc/freeradius/sites-available Verzeichnis.
- /etc/freeradius/sites-available/default
authorize {
preprocess
chap
mschap
suffix
eap {
ok = return
}
unix
sql # aktivieren
expiration
logintime
pap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
unix
eap
}
preacct {
preprocess
acct_unique
suffix
files
}
accounting {
detail
unix
radutmp
sql # aktivieren
attr_filter.accounting_response
}
session {
radutmp
sql # aktivieren
}
post-auth {
exec
Post-Auth-Type REJECT {
attr_filter.access_reject
}
}
pre-proxy {
}
post-proxy {
eap
}
|
Hier müssen die entsprechend auskommentierten SQL Zeilen von ihrem Kommentarzeichen befreit werden. Vor allem die Zeilen session müssen aktiviert werden.
Zu guter letzt wird die Client Konfiguration vom Radius Server angepasst:
- /etc/freeradius/clients.conf
client localhost {
ipaddr = 127.0.0.1
secret = radiussecret
require_message_authenticator = no
}
|
Radius Benutzer hinzufügen
Nun können wir zwei Benutzer für Radius hinzufügen, welche in die Datenbank eingepflegt werden:
spot01 ~ # echo "INSERT INTO radcheck (UserName, Attribute, Value) VALUES ('guest', 'Password','guest');" | mysql -u radius -pradspot01 radius
spot01 ~ # echo "INSERT INTO radcheck (UserName, Attribute, Value) VALUES ('chillispot', 'Password','chillipass');" | mysql -u radius -pradiuspass radius
|
Es werden also zwei Benutzer hinzugefügt:
- Benutzer: guest - Passwort: guest
- Benutzer: chillispot - Passwort: chillipass
Der erste Benutzer dient später dazu, um unseren W-Lan Clients einen freien Internet Zugang zu gewähren, wenn sie einem Disclaimer zugestimmt haben. Der zweite Benutzer wird von Coova Chilli verwendet. Um die Funktionsfähigkeit zu überprüfen, kann dies mit Hilfe von radtest geschehen.
spot01 ~ # /etc/init.d/freeradius restart spot01 ~ # radtest guest guest 127.0.0.1 0 radiussecret Sending Access-Request of id 203 to 127.0.0.1 port 1812 User-Name = "guest" User-Password = "guest" NAS-IP-Address = 127.0.1.1 NAS-Port = 0 rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=203, length=2 |
Hier kann man nun erkennen, dass die Verbindung erfolgreich war. Sollte es nicht klappen, so lohnt sich der Debugaufruf mittels freeradius -XX. Dazu muss jedoch der Radius Server vorher gestoppt werden, wenn er denn laufen sollte!
Coova CHilli
Nach den Vorarbeiten, kann nun die Installation und Konfiguration von Chilli erfolgen.
Installation Chilli
Es gibt ein fertiges Paket für Debian Distributionen, welches installiert werden kann. Dazu laden wir es herunter und installieren es per dpkg:
- Installieren
spot01 ~ # wget http://ap.coova.org/chilli/coova-chilli_1.0.12-1_i386.deb spot01 ~ # dpkg -i coova-chilli_1.0.12-1_i386.deb |
Webseite Vorarbeiten
Nun müssen ein paar Dateien und Verzeichnisse für die Webseite erstellt und mit Inhalt gefüllt werden.
- Für die Webseite
spot01 ~ # cp /etc/chilli/defaults /etc/chilli/config spot01 ~ # mkdir -p /var/www/hotspot/uam spot01 ~ # cp /etc/chilli/www/* /var/www/hotspot |
Als erstes kopieren wir die Standard Konfigurations- Datei für Chilli um. Dann wird die Struktur für den späteren HotSpotLogin erstellt, den die Benutzer zu Gesicht bekommen werden.
spot01 ~ # cd /var/www/hotspot/uam spot01 ~ # wget http://ap.coova.org/uam/ spot01 ~ # wget http://ap.coova.org/js/chilli.js |
Hier wird eine Standardseite bezogen, welche einige JavaScript Sachen bereithält, die für die spätere Session nötig werden.
Ruft ein Gast eine Webseite auf, so wird er auf die index.html in dem Verzeichnis /var/www/hotspot/uam umgeleitet, welche wiederum selbst eine Umleitung vornimmt. Diese wird ins Leere laufen, solang die dort enthaltene Adresse nicht durch die eigene ausgetauscht wird. Ein kurzer sed Aufruf löst diese Problem:
spot01~ # sed -i 's/coova.org\/js\/chilli.js/10.1.0.1\/uam\/chilli.js/g' /var/www/hotspot/uam/index.html |
Damit ändern wir also den Umleitung von coova.org auf die IP Adresse 10.1.0.1 (unserem Coova Chilli Spot) um. Sofern ein DNS Server bereit steht, kann das natürlich erneut ein Name sein.
Chiili Konfiguration
Damit Coova Chilli automatisch startet, bedarf es einer kleinen Anpassung:
- /etc/default/chilli
START_CHILLI=1 |
Als nächstes wird nun Chilli selbst konfiguriert. Dazu wieder eine von normalen Kommentaren befreite Datei:
- /etc/chilli/config
# Die Externe Netzwerkkarte zum Internet HS_WANIF=eth0 # Die Interne Netzwerkkarte zu den HotSpot Clients HS_LANIF=eth1 # Das gewünsche Netzwerk für die Hotspot Clients HS_NETWORK=10.1.0.0 # Die Netzwerkmaske dazu HS_NETMASK=255.255.255.0 # HotSpot Network Netmask # Die IP Adresse, an der Chilli lauschen soll incl. DHCP Server. Muss zum Netz oben pssen! HS_UAMLISTEN=10.1.0.1 # Der Port, an dem Chilli lauscht. Auf diesen greifen die HotSpot Clients zu HS_UAMPORT=3990 # Der DNS Server, welcher den Clients mitgegeben wird HS_DNS1=10.1.0.1 # Eine ID HS_NASID=nas01 # Das Kennwort auf den später das CGI Login Script "hotspotlogin.cgi" zugreift HS_UAMSECRET=spotsecret # Wo ist der erste Radius Server zu finden HS_RADIUS=localhost # Wo ist der zweite Radius Server zu finden HS_RADIUS2=localhost # Mit welchem Kennwort greifen wir zu, siehe: /etc/freeradius/clients.conf HS_RADSECRET=radiussecret # Auf welche DNS/IP Adressen dürfen die HotSpot Clients zugreifen, ohne Authentifizierung! HS_UAMALLOW=10.1.0.0/24 # Wo befindet sich die Loginserver, auf die die Clients umgeleitet werden HS_UAMSERVER=10.1.0.1/cgi-bin/hotspotlogin.cgi # Welche Seite wird aufgerufen HS_UAMFORMAT=https://\$HS_UAMSERVER/uam/chilli # Was ist die Standardwebseite HS_UAMHOMEPAGE=http://\$HS_UAMLISTEN:\$HS_UAMPORT/www/coova.html # Unbekannt ??? HS_UAMSERVICE=https://10.1.0.1/uam/auth # Soll angebelich für viele Seiten benötigt werden, die google Map eingebettet haben HS_USE_MAP=on # Wenn im Radius kein Session Timeout definiert wurde, wann fliegt der Hotspot User wieder raus HS_DEFSESSIONTIMEOUT=900 # In Sekunden # Wenn nichts passiert, wann fliegt der Hotspot User raus HS_DEFIDLETIMEOUT=900 # In Sekunden # Der Modus HS_MODE=hotspot # Der Typ HS_TYPE=chillispot # Benutzer in der Datenbank HS_ADMUSR=chillispot # Passwort vom User chillispot in der Datenbank HS_ADMPWD=chillipass # Das Stammverzeichnis von der Webseite HS_WWWDIR=/var/www/hotspot # Die Benärdatei wwwsh HS_WWWBIN=/etc/chilli/wwwsh # Freier Name für den Hotspot HS_LOC_NAME="KBB Spot1" # WISPr Location Name and used in portal |
Firewall Script
Bei jedem Start von Chilli Spot und nach der Anmeldung eines HotSpot Clients, werden Aktionen ausgelöst, wie z.B. das setzen von Firewall Regeln. Darin kann bestimmt werden, welche Ports dem Benutzer zur Verfügung stehen sollen. Dieses Script kann unter dem Namen /etc/chilli/ipup.sh abgelegt werden:
- /etc/chilli/ipup.sh
#!/bin/sh # # Firewall script for ChilliSpot # A Wireless LAN Access Point Controller # # Uses $EXTIF (eth0) as the external interface (Internet or intranet) and # $INTIF (eth1) as the internal interface (access points). # # # SUMMARY # * All connections originating from chilli are allowed. # * Only ssh is allowed in on external interface. # * Nothing is allowed in on internal interface. # * Forwarding is allowed to and from the external interface, but disallowed # to and from the internal interface. # * NAT is enabled on the external interface. IPTABLES="/sbin/iptables" EXTIF="eth0" INTIF="eth1" $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD ACCEPT $IPTABLES -P OUTPUT ACCEPT #Allow related and established on all interfaces (input) $IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT #Allow releated, established and ssh on $EXTIF. Reject everything else. $IPTABLES -A INPUT -i $EXTIF -p tcp -m tcp --dport 22 --syn -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -j REJECT #Allow related and established from $INTIF. Drop everything else. $IPTABLES -A INPUT -i $INTIF -j DROP #Allow http and https on other interfaces (input). #This is only needed if authentication server is on same server as chilli $IPTABLES -A INPUT -p tcp -m tcp --dport 80 --syn -j ACCEPT $IPTABLES -A INPUT -p tcp -m tcp --dport 443 --syn -j ACCEPT #Allow 3990 on other interfaces (input). $IPTABLES -A INPUT -p tcp -m tcp --dport 3990 --syn -j ACCEPT #Allow everything on loopback interface. $IPTABLES -A INPUT -i lo -j ACCEPT # Drop everything to and from $INTIF (forward) # This means that access points can only be managed from ChilliSpot $IPTABLES -A FORWARD -i $INTIF -j DROP $IPTABLES -A FORWARD -o $INTIF -j DROP #Enable NAT on output device $IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE |
Das Script muss natürlich ausführbar sein:
spot01 ~ # chmod +x /etc/chilli/ipup.sh |
Apache
Nun folgt die Apache2 Konfiguration. Zum einen benötigen wir einen Virtual Host der CGI Dateien ausführen darf, zum anderen soll er über SSL arbeiten.
Vorarbeit
Wir erzeugen ein CGI Verzeichnis und kopieren eine Beispiel hotspotlogin.cg hinein:
spot01 ~ # mkdir -p /var/www/hotspot/cgi-bin spot01 ~ # zcat /usr/share/doc/coova-chilli/hotspotlogin.cgi.gz > /var/www/hotspot/cgi-bin/hotspotlogin.cgi spot01 ~ # chmod a+x /var/www/hotspot/cgi-bin/hotspotlogin.cgi |
Damit die CGI Datei hotspotlogin.cgi mit dem Chilli Server kommunizieren kann, muss die Authentifizierung aktiviert, sowie das Passwort angegeben werden. Dazu passen wir diese Datei an
- /var/www/hotspot/cgi-bin/hotspotlogin.cgi
[...] # Siehe /etc/chilli/config -> HS_UAMSECRET $uamsecret = "spotsecret"; $userpassword=1; [..] |
Apache SSL
Da die Datei hotspotlogin.cgi erwartet, dass der HotSpot User über eine HTTPS Adresse kommt, benötigen wir daher einen SSL aktivierten Apachen. Um das dafür nötige Zertifikat bequem zu erstellen, eignet sich das Paket ssl-cert. Mit dem richtigen Aufruf erledigt er alles dafür nötige:
spot01 ~ # apt-get install apache2 ssl-cert spot01 ~ # mkdir /etc/apache2/ssl spot01 ~ # hostname -f |
Die letzte Ausgabe merken, da wir sie für das Zertifikat benötigen:
spot01 ~ # make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem |
Bei der Frage für den CommonName bitte die Ausgabe von hostname -f eintragen.
Nun wird das SSL Modul vom Apachen noch aktiviert:
- SSL Modul aktivieren
spot01 ~ # a2enmod ssl |
Virtual Host
Nun können wir den Virtual Host erstellen und aktivieren:
- /etc/apache2/sites-available/hotspot
NameVirtualHost 10.1.0.1:443
<VirtualHost 10.1.0.1:443>
ServerAdmin hotpot@wireless.local
DocumentRoot "/var/www/hotspot"
ServerName "spot01.wireless.local"
<Directory "/var/www/hotspot/">
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
Alias "/dialupadmin/" "/usr/share/freeradius-dialupadmin/htdocs/"
<Directory "/usr/share/freeradius-dialupadmin/htdocs/">
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /var/www/hotspot/cgi-bin/
<Directory "/var/www/hotspot/cgi-bin/">
AllowOverride None
Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/hotspot-error.log
LogLevel warn
CustomLog /var/log/apache2/hotspot-access.log combined
ServerSignature On
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem
</VirtualHost>
|
- Virtual Host aktivieren
spot01 ~ # a2ensite hotspot spot01 ~ # apache2ctl -t spot01 ~ # /etc/init.d/apache2 reload |
Wer möchte, kann auch noch die Hautpkonfiguration vom Apache anpasen. Anbieten würde sich z.B. der Servername:
- /etc/apache2/apache2.conf
{{code|
[...] ServerName 10.1.0.1 [...]
Den Syntax check und ein anschließendes reload nicht vergessen.
Testen
Sind all die Arbeiten abgeschlossen worden, kann nun getestet werden. Der Autor hat hierzu alles in Vmware laufen und kann so beliebige Tests ausführen. Wichtig ist hierbei die richtige Reihenfolge der Dienste:
- /etc/init.d/mysql restart
- /etc/init.d/freeradius restart
- /etc/init.d/chilli restart
- /etc/init.d/apache2 restart
Beim start des Hotspot Clients muss dieser eine IP Adresse vom Chilli DHCP Server erhalten haben. Des weiteren wurde auch der DNS Server mitgegeben. Beim öffnen einer beliebigen Webseite vom Hotspot Client, wird die Seite umgeleitet auf die hotspotlogin.cgi Seite. Eventuell gibt es ein Warnhinweis, aufgrund des selbstsignierten SSL Zertifikat. Wurde die Login Seite geöffnet, kann nun der Benutzer "guest" und das Passwort "guest" verwendet werden. Hat alles geklappt, sollte der Zugang zum Internet nun möglich sein. Ein eigenes Fenster klärt über den Status auf.
eth1 wird zu tun0
Wird Chili gestartet, so wird die IP Adresse und der DHCP Server auf das Interface tun0 gelegt, welches in diesem Moment entsteht. Daher ist es wichtig, dass die eth1 nicht konfiguriert wird. Im gleichen Atemzug muss daher das Modul für tun vorhanden sein. Dies kann leicht mit modprobe tun festgestellt werden.
DNS Server
Sollte bisher noch kein DNS Server vorhanden sein, so eignet sich am besten ein Cachin Name Server, wie DNSMasq:
spot01 ~ # apt-get install dnsmasq |
Er bedarf keiner Konfiguration mehr. Einzig in der /etc/resolv.conf sollten mindestens zwei richtige DNS Server vorhanden sein. Nach einem Neustart von dnsmasq steht er den HotSpot Clients zur Verfügung.
HotSpotLogin.cgi anpassen
Sind alle diese Arbeiten abgeschlossen, kann als nächstes die hotspotlogin.cgi Datei dahingehend angepasst werden, dass lediglich ein Disclaimer verwendet wird, dem die HotSpot Clients zustimmen müssen.
Dazu öffnen wir erneut die Datei und springen zur Zeile 387.
Ab dort befinden sich die entsprechenden Zeilen. Der Benutzername und das Kennwort werden hier abgefragt. Nun müssen wir nichts anderes unternehmen, als diese Felder zu befüllen und zu verstecken:
- Aus diesen Zeilen ...
<center>
<table border=\"0\" cellpadding=\"5\" cellspacing=\"0\" style=\"width: 217px;\">
<tbody>
<tr>
<td align=\"right\">Username:</td>
<td><input STYLE=\"font-family: Arial\" type=\"text\" name=\"UserName\" size=\"20\" maxlength=\"128\"></td>
</tr>
<tr>
<td align=\"right\">Password:</td>
<td><input STYLE=\"font-family: Arial\" type=\"password\" name=\"Password\" size=\"20\" maxlength=\"128\"></td>
</tr>
<tr>
<td align=\"center\" colspan=\"2\" height=\"23\"><input type=\"submit\" name=\"button\" value=\"Login\" onClick=\"javascript:popUp('$loginpath?res=popup1&uamip=$uamip&uamport=$uamport')\"></td>
</tr>
</tbody>
</table>
</center>
|
- Werden diese Zeilen ...
<center>
<table border=\"0\" cellpadding=\"5\" cellspacing=\"0\" style=\"width: 217px;\">
<tbody>
<tr>
<!-- <td align=\"right\">Benutzername:</td> -->
<td><input TYPE=\"hidden\" STYLE=\"font-family: Arial\" type=\"text\" name=\"UserName\" size=\"20\" value=\"guest\" maxlength=\"128\"></td>
</tr>
<!-- DISCLAIMER einbinden-->
<tr>
Wenn sie auf \"Login\" klicken. Stimmen sie unserem Disclaimer zu!
</tr>
<!-- DISCLAIMER Ende -->
<tr>
<!-- <td align=\"right\">Passwort:</td> -->
<td><input TYPE=\"hidden\" STYLE=\"font-family: Arial\" type=\"password\" name=\"Password\" size=\"20\" value=\"guest\" maxlength=\"128\"></td>
</tr>
<tr>
<td align=\"center\" colspan=\"2\" height=\"23\">AGB akzeptieren: <input type=\"submit\" name=\"button\" value=\"Login\" onClick=\"javascript:popUp('$loginpath?res=popup1&uamip=$uamip&uamport=$uamport')\"></td>
</tr>
</tbody>
</table>
</center>
|
Im Zweiten Teil werden die Felder für Benutzernamen und Passwort versteckt. Natürlich ist dies nicht besonders schön, zumal Anführungszeichen maskiert werden müssen. Daher gibt es noch eine weit elegantere Lösung. wir können das Script so anpassen, dass eine externe HTML Datei eingelesen wird. Der Inhalt davon, wird an der Stelle positioniert, wo wir eine entsprechende Variable unterbringen. Dazu müssen wir erneut ein paar Zeilen hinzufügen. Dies geschieht ab der Zeile 387
[...]
if ($result == 5) {
print "
<h1 style=\"text-align: center;\">Hotspot Login</h1>";
}
if ($result == 2 || $result == 5) {
[...]
Zwischen der if ($result == 5) {' und der print Zeile, kommen nun folgende Zeilen:
my $inpath="/var/www/hotspot/disclaimer/disclaimer.html";
open IN,"$inpath" || die "cannot open $inpath for read\n\n";
my $disclaimer="";
while (my $l=<IN>) {
chomp $l;
$disclaimer="$disclaimer" . "$l";
}
Damit wird nun die Datei /var/www/hotspot/disclaimer/disclaimer.htm eingelesen. Damit sie an der passenden Stelle eingepflegt wird, kommt nun die Variable $disclaimer zum zuge.
<tr>
<!-- <td align=\"right\">Benutzername:</td> -->
<td><input TYPE=\"hidden\" STYLE=\"font-family: Arial\" type=\"text\" name=\"UserName\" size=\"20\" value=\"guest\" maxlength=\"128\"></td>
</tr>
<!-- DISCLAIMER einbinden-->
$disclaimer
<!-- DISCLAIMER Ende -->
<tr>
<!-- <td align=\"right\">Passwort:</td> -->
<td><input TYPE=\"hidden\" STYLE=\"font-family: Arial\" type=\"password\" name=\"Password\" size=\"20\" value=\"guest\" maxlength=\"128\"></td>
</tr>
<tr>
Hat alles geklappt, kann nun sehr leicht der Disclaimer ausgetauscht werden. Dabei können wieder sämtliche HTML Befehle zum Einsatz kommen. Es können nun auch Bilder etc. mit eingebunden werden.
Logging
Wer auf ein Logging angewiesen ist, der kann sehr bequem per SLQ Abfrage die dazu nötigen Tabellen abfragen. In dem nachfolgendem Beispiel werden die Zugriffe vom Benutzer "guest" abgerufen:
spot01 ~ # mysql -uradius -pradiuspass radius -e 'select AcctUniqueId,acctstarttime,acctstoptime,callingstationid,FramedIPAddress from radacct where username="guest"' |
Heraus kommt diese Auflistung:
+------------------+---------------------+---------------------+-------------------+-----------------+ | AcctUniqueId | acctstarttime | acctstoptime | callingstationid | FramedIPAddress | +------------------+---------------------+---------------------+-------------------+-----------------+ | 5193b45afce960fc | 2009-03-05 16:29:59 | 2009-03-05 16:45:02 | 00-0C-29-DD-FA-E7 | 10.1.0.2 | | 090e966bc520bff6 | 2009-03-05 17:01:06 | NULL | 00-0C-29-DD-FA-E7 | 10.1.0.2 | +------------------+---------------------+---------------------+-------------------+-----------------+
- Aufbau
- AcctUniqueId - Eindeutige Session ID
- acctstarttime - Session Startzeit
- acctstoptime - Session Endzeit
- callingstationid - Client MAC Adresse
- FramedIPAddress - Zugewiesene IP Adresse
Natürlich können noch weitere Tabellen abgefragt werden. Einfach die passenden heraussuchen.
Anhang
hotspotlogin.cgi
# Shared secret used to encrypt challenge with. Prevents dictionary attacks.
# You should change this to your own shared secret.
$uamsecret = "ahhie3Ju";
# Uncomment the following line if you want to use ordinary user-password
# for radius authentication. Must be used together with $uamsecret.
$userpassword=1;
# This code is horrible -- it came that way, and remains that way. A
# real open-source captive portal for coova-chilli should be built -- david
$loginpath = "/cgi-bin/hotspotlogin.cgi";
use Digest::MD5 qw(md5 md5_hex md5_base64);
# Make sure that the form parameters are clean
$OK_CHARS='-a-zA-Z0-9_.@&=%!';
$_ = $input = <STDIN>;
s/[^$OK_CHARS]/_/go;
$input = $_;
# Make sure that the get query parameters are clean
$OK_CHARS='-a-zA-Z0-9_.@&=%!';
$_ = $query=$ENV{QUERY_STRING};
s/[^$OK_CHARS]/_/go;
$query = $_;
# If she did not use https tell her that it was wrong.
if (!($ENV{HTTPS} =~ /^on$/)) {
print "Content-type: text/html\n\n
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>ChilliSpot Login Failed</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">
</head>
<body bgColor = '#c0d8f4'>
<h1 style=\"text-align: center;\">HotSpot Login Failed</h1>
<center>
Login must use encrypted connection.
</center>
</body>
<!--
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<WISPAccessGatewayParam
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:noNamespaceSchemaLocation=\"http://www.acmewisp.com/WISPAccessGatewayParam.xsd\">
<AuthenticationReply>
<MessageType>120</MessageType>
<ResponseCode>102</ResponseCode>
<ReplyMessage>Login must use encrypted connection</ReplyMessage>
</AuthenticationReply>
</WISPAccessGatewayParam>
-->
</html>
";
exit(0);
}
#Read form parameters which we care about
@array = split('&',$input);
foreach $var ( @array )
{
@array2 = split('=',$var);
if ($array2[0] =~ /^username$/i) { $username = $array2[1]; }
if ($array2[0] =~ /^password$/i) { $password = $array2[1]; }
if ($array2[0] =~ /^challenge$/) { $challenge = $array2[1]; }
if ($array2[0] =~ /^button$/) { $button = $array2[1]; }
if ($array2[0] =~ /^logout$/) { $logout = $array2[1]; }
if ($array2[0] =~ /^prelogin$/) { $prelogin = $array2[1]; }
if ($array2[0] =~ /^res$/) { $res = $array2[1]; }
if ($array2[0] =~ /^uamip$/) { $uamip = $array2[1]; }
if ($array2[0] =~ /^uamport$/) { $uamport = $array2[1]; }
if ($array2[0] =~ /^userurl$/) { $userurl = $array2[1]; }
if ($array2[0] =~ /^timeleft$/) { $timeleft = $array2[1]; }
if ($array2[0] =~ /^redirurl$/) { $redirurl = $array2[1]; }
}
#Read query parameters which we care about
@array = split('&',$query);
foreach $var ( @array )
{
@array2 = split('=',$var);
if ($array2[0] =~ /^username$/i) { $username = $array2[1]; }
if ($array2[0] =~ /^password$/i) { $password = $array2[1]; }
if ($array2[0] =~ /^res$/) { $res = $array2[1]; }
if ($array2[0] =~ /^challenge$/) { $challenge = $array2[1]; }
if ($array2[0] =~ /^uamip$/) { $uamip = $array2[1]; }
if ($array2[0] =~ /^uamport$/) { $uamport = $array2[1]; }
if ($array2[0] =~ /^reply$/) { $reply = $array2[1]; }
if ($array2[0] =~ /^userurl$/) { $userurl = $array2[1]; }
if ($array2[0] =~ /^timeleft$/) { $timeleft = $array2[1]; }
if ($array2[0] =~ /^redirurl$/) { $redirurl = $array2[1]; }
}
$reply =~ s/\+/ /g;
$reply =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;
$userurldecode = $userurl;
$userurldecode =~ s/\+/ /g;
$userurldecode =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;
$redirurldecode = $redirurl;
$redirurldecode =~ s/\+/ /g;
$redirurldecode =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;
$password =~ s/\+/ /g;
$password =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg;
# If attempt to login
if ($button =~ /^Login$/) {
$hexchal = pack "H32", $challenge;
if (defined $uamsecret) {
$newchal = md5($hexchal, $uamsecret);
}
else {
$newchal = $hexchal;
}
$response = md5_hex("\0", $password, $newchal);
$pappassword = unpack "H32", ($password ^ $newchal);
#sleep 5;
print "Content-type: text/html\n\n";
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>ChilliSpot Login</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">";
if ((defined $uamsecret) && defined($userpassword)) {
print " <meta http-equiv=\"refresh\" content=\"0;url=http://$uamip:$uamport/logon?username=$username&password=$pappassword\">";
} else {
print " <meta http-equiv=\"refresh\" content=\"0;url=http://$uamip:$uamport/logon?username=$username&response=$response&userurl=$userurl\">";
}
print "</head>
<body bgColor = '#c0d8f4'>";
print "<h1 style=\"text-align: center;\">Logging in to ChilliSpot</h1>";
print "
<center>
Please wait......
</center>
</body>
<!--
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<WISPAccessGatewayParam
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:noNamespaceSchemaLocation=\"http://www.acmewisp.com/WISPAccessGatewayParam.xsd\">
<AuthenticationReply>
<MessageType>120</MessageType>
<ResponseCode>201</ResponseCode>
";
if ((defined $uamsecret) && defined($userpassword)) {
print "<LoginResultsURL>http://$uamip:$uamport/logon?username=$username&password=$pappassword</LoginResultsURL>";
} else {
print "<LoginResultsURL>http://$uamip:$uamport/logon?username=$username&response=$response&userurl=$userurl</LoginResultsURL>";
}
print "</AuthenticationReply>
</WISPAccessGatewayParam>
-->
</html>
";
exit(0);
}
# Default: It was not a form request
$result = 0;
# If login successful
if ($res =~ /^success$/) {
$result = 1;
}
# If login failed
if ($res =~ /^failed$/) {
$result = 2;
}
# If logout successful
if ($res =~ /^logoff$/) {
$result = 3;
}
# If tried to login while already logged in
if ($res =~ /^already$/) {
$result = 4;
}
# If not logged in yet
if ($res =~ /^notyet$/) {
$result = 5;
}
# If login from smart client
if ($res =~ /^smartclient$/) {
$result = 6;
}
# If requested a logging in pop up window
if ($res =~ /^popup1$/) {
$result = 11;
}
# If requested a success pop up window
if ($res =~ /^popup2$/) {
$result = 12;
}
# If requested a logout pop up window
if ($res =~ /^popup3$/) {
$result = 13;
}
# Otherwise it was not a form request
# Send out an error message
if ($result == 0) {
print "Content-type: text/html\n\n
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>HostSpot Login fehlgeschlagen</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">
</head>
<body bgColor = '#c0d8f4'>
<h1 style=\"text-align: center;\">ChilliSpot Login Failed</h1>
<center>
Login must be performed through ChilliSpot daemon.
</center>
</body>
</html>
";
exit(0);
}
#Generate the output
print "Content-type: text/html\n\n
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<title>HotSpot Login</title>
<meta http-equiv=\"Cache-control\" content=\"no-cache\">
<meta http-equiv=\"Pragma\" content=\"no-cache\">
<SCRIPT LANGUAGE=\"JavaScript\">
var blur = 0;
var starttime = new Date();
var startclock = starttime.getTime();
var mytimeleft = 0;
function doTime() {
window.setTimeout( \"doTime()\", 1000 );
t = new Date();
time = Math.round((t.getTime() - starttime.getTime())/1000);
if (mytimeleft) {
time = mytimeleft - time;
if (time <= 0) {
window.location = \"$loginpath?res=popup3&uamip=$uamip&uamport=$uamport\";
}
}
if (time < 0) time = 0;
hours = (time - (time % 3600)) / 3600;
time = time - (hours * 3600);
mins = (time - (time % 60)) / 60;
secs = time - (mins * 60);
if (hours < 10) hours = \"0\" + hours;
if (mins < 10) mins = \"0\" + mins;
if (secs < 10) secs = \"0\" + secs;
title = \"Online time: \" + hours + \":\" + mins + \":\" + secs;
if (mytimeleft) {
title = \"Remaining time: \" + hours + \":\" + mins + \":\" + secs;
}
if(document.all || document.getElementById){
document.title = title;
}
else {
self.status = title;
}
}
function popUp(URL) {
if (self.name != \"chillispot_popup\") {
chillispot_popup = window.open(URL, 'chillispot_popup', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=375');
}
}
function doOnLoad(result, URL, userurl, redirurl, timeleft) {
if (timeleft) {
mytimeleft = timeleft;
}
if ((result == 1) && (self.name == \"chillispot_popup\")) {
doTime();
}
if ((result == 1) && (self.name != \"chillispot_popup\")) {
chillispot_popup = window.open(URL, 'chillispot_popup', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=375');
}
if ((result == 2) || result == 5) {
document.form1.UserName.focus()
}
if ((result == 2) && (self.name != \"chillispot_popup\")) {
chillispot_popup = window.open('', 'chillispot_popup', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=400,height=200');
chillispot_popup.close();
}
if ((result == 12) && (self.name == \"chillispot_popup\")) {
doTime();
if (redirurl) {
opener.location = redirurl;
}
else if (opener.home) {
opener.home();
}
else {
opener.location = \"about:home\";
}
self.focus();
blur = 0;
}
if ((result == 13) && (self.name == \"chillispot_popup\")) {
self.focus();
blur = 1;
}
}
function doOnBlur(result) {
if ((result == 12) && (self.name == \"chillispot_popup\")) {
if (blur == 0) {
blur = 1;
self.focus();
}
}
}
</script>
</head>
<body onLoad=\"javascript:doOnLoad($result, '$loginpath?res=popup2&uamip=$uamip&uamport=$uamport&userurl=$userurl&redirurl=$redirurl&timeleft=$timeleft','$userurldecode', '$redirurldecode', '$timeleft')\" onBlur = \"javascript:doOnBlur($result)\" bgColor = '#c0d8f4'>";
# if (!window.opener) {
# document.bgColor = '#c0d8f4';
# }
#print "THE INPUT: $input";
#foreach $key (sort (keys %ENV)) {
# print $key, ' = ', $ENV{$key}, "<br>\n";
#}
if ($result == 2) {
print "
<h1 style=\"text-align: center;\">HotSpot Login fehlgeschlagen</h1>";
if ($reply) {
print "<center> $reply </BR></BR></center>";
}
}
if ($result == 5) {
print "
<h1 style=\"text-align: center;\">Hotspot Login</h1>";
}
if ($result == 2 || $result == 5) {
my $inpath="/var/www/hotspot/disclaimer/disclaimer.html";
open IN,"$inpath" || die "cannot open $inpath for read\n\n";
my $disclaimer="";
while (my $l=<IN>) {
chomp $l;
$disclaimer="$disclaimer" . "$l";
}
print "
<form name=\"form1\" method=\"post\" action=\"$loginpath\">
<INPUT TYPE=\"hidden\" NAME=\"challenge\" VALUE=\"$challenge\">
<INPUT TYPE=\"hidden\" NAME=\"uamip\" VALUE=\"$uamip\">
<INPUT TYPE=\"hidden\" NAME=\"uamport\" VALUE=\"$uamport\">
<INPUT TYPE=\"hidden\" NAME=\"userurl\" VALUE=\"$userurl\">
<!--#include virtual=\"index.shtml\"-->
<center>
<table border=\"0\" cellpadding=\"5\" cellspacing=\"0\" style=\"width: 217px;\">
<tbody>
<tr>
<!-- <td align=\"right\">Benutzername:</td> -->
<td><input TYPE=\"hidden\" STYLE=\"font-family: Arial\" type=\"text\" name=\"UserName\" size=\"20\" value=\"guest\" maxlength=\"128\"></td>
</tr>
<!-- DISCLAIMER einbinden-->
$disclaimer
<!-- DISCLAIMER Ende -->
<tr>
<!-- <td align=\"right\">Passwort:</td> -->
<td><input TYPE=\"hidden\" STYLE=\"font-family: Arial\" type=\"password\" name=\"Password\" size=\"20\" value=\"guest\" maxlength=\"128\"></td>
</tr>
<tr>
<td align=\"center\" colspan=\"2\" height=\"23\">AGB akzeptieren: <input type=\"submit\" name=\"button\" value=\"Login\" onClick=\"javascript:popUp('$loginpath?res=popup1&uamip=$uamip&uamport=$uamport')\"></td>
</tr>
</tbody>
</table>
</center>
</form>
</body>
</html>";
}
if ($result == 1) {
print "
<h1 style=\"text-align: center;\">Logged in to ChilliSpot</h1>";
if ($reply) {
print "<center> $reply </BR></BR></center>";
}
print "
<center>
<a href=\"http://$uamip:$uamport/logoff\">Logout</a>
</center>
</body>
</html>";
}
if (($result == 4) || ($result == 12)) {
print "
<h1 style=\"text-align: center;\">Logged in to ChilliSpot</h1>
<center>
<a href=\"http://$uamip:$uamport/logoff\">Logout</a>
</center>
</body>
</html>";
}
if ($result == 11) {
print "<h1 style=\"text-align: center;\">Logging in to ChilliSpot</h1>";
print "
<center>
Please wait......
</center>
</body>
</html>";
}
if (($result == 3) || ($result == 13)) {
print "
<h1 style=\"text-align: center;\">Logged out from ChilliSpot</h1>
<center>
<a href=\"http://$uamip:$uamport/prelogin\">Login</a>
</center>
</body>
</html>";
}
exit(0);
Quellen
- FreeRadius - http://www.freeradius.org
- CoovaChilli Webseite - http://coova.org/wiki/index.php/CoovaChilli
- Cooca chilli - Ubuntu Installation
--Denny 22:12, 11. Mär. 2009 (UTC)