Installing Chillispot on FreeBSD By Sevan Janiyan www.geeklan.co.uk venture37@geeklan.co.uk This guide will cover how to get a basic Chillispot installation going with Apache 1.3 + mod_ssl, mySQL 4.1, freeRADIUS & OpenBSD's Packet Filter PF 1) Update your ports tree!!!! Instructions on how to do so are included in the HandBook under the Using CVSup section: http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/cvsup.html 2) Once the update is complete goto {PORTSDIR}/net-mgmt/chillispot & run make install, you'll be presented with a menu, select: MATURE Stable Releases of Apache with mod_ssl & mySQL & FREE freeRADIUS & choose Ok During the build process you'll be asked what flavour of freeRADIUS you'd like to build, choose MYSQL With MySQL user database 3) When the build & install process is complete go back to the apache directory, regenerate & install some new certs & optionally remove the preinstalled snakeoil test ones. goto {PORTSDIR}/www/apache13-modssl & run make certificate TYPE=custom Answer the questions in each step & when you're finished you'll be given a summary of files & their functions Now copy those files from the summary by going to work/apache_1.X.XX/conf & copy the certs to your apache config directory (replace X.XX with the relevant version number) cp work/apache_1.X.XX/conf/ssl.key/ca.key %%PREFIX%%/etc/apache/ssl.key/ cp work/apache_1.XXX/conf/ssl.key/server.key %%PREFIX%%/etc/apache/ssl.key/ cp work/apache_1.XXX/conf/ssl.crt/ca.crt %%PREFIX%%/etc/apache/ssl.crt/ cp work/apache_1.XXX/conf/ssl.crt/server.crt %%PREFIX%%/etc/apache/ssl.crt/ chmod 400 %%PREFIX%%/etc/apache/ssl.key/ca.key chmod 400 %%PREFIX%%/etc/apache/ssl.crt/ca.crt Optional: rm %%PREFIX%%/etc/apache/ssl.key/snakeoil-* rm %%PREFIX%%/etc/apache/ssl.crt/snakeoil-* then goto %%PREFIX%%/etc/apache/ssl.crt/ & delete the bunch of alphanumeric filenamed symbolic links 4) Put Chillispots files into place: copy hotspotlogin.cgi from %%PREFIX%%/share/chillispot/ to %%PREFIX%%/www/cgi/ & make it executable: chmod 555 %%PREFIX%%/www/cgi-bin/hotspotlogin.cgi put chillispot.conf file into place cp %%PREFIX%%/share/chillispot/chilli.conf.sample %%PREFIX%%/etc/chilli.conf freeRADIUS related files cp %%PREFIX%%/share/chillispot/dictionary.chillispot %%PREFIX%%/etc/raddb/ cp %%PREFIX%%/share/chillispot/freeradius.users %%PREFIX%%/etc/raddb/ PF Config file cp %%PREFIX%%/share/chillispot/pf.conf.sample /etc/pf.conf 5) Setup MySQL run ./mysql_install_db & follow the onscreen instructions provided to set a new root password 6) Create a Database for freeRADIUS at the mysql prompt issue the following: create database mydbname; grant all privileges on mydbname.* to 'dbusername'@'localhost' identified by 'mypass'; flush privileges; quit; 7) Import the freeRADIUS MySQL DB Schema by running the following: mysql -u dbusrname -p mydbname < %%PREFIX%%/share/doc/freeradius/examples/mysql.sql 8) Configure freeRADIUS goto %%PREFIX%%/etc/raddb trim .sample from the end of the filenames off the following files: acct_users certs clients.conf dictionary , then edit if & add $INCLUDE dictionary.chillispot eap.conf hints huntgroups preproxy_users proxy.conf radiusd.conf snmp.conf sql.conf users 9) Before going ahead & configuring freeRADIUS to use MySQL setup a basic account using the existing flatfiles to make sure everything is working so far edit %%PREFIX%%/etc/raddb/clients.conf & change the secret entry e.g: secret = s3cr3t then add the sample chillispot user by copying the contents of freeradius.users to users then run adduser to create a user which radiusd will run under #adduser Username: radiusd Full name: freeRADIUS Uid (Leave empty for default): Login group [radiusd]: Login group is radiusd. Invite radiusd into other groups? []: Login class [default]: Shell (sh csh tcsh nologin) [sh]: nologin Home directory [/home/radiusd]: /nonexistent Use password-based authentication? [yes]: Use an empty password? (yes/no) [no]: Use a random password? (yes/no) [no]: y Lock out the account after creation? [no]: y Username : radiusd Password : Full Name : freeRADIUS Uid : 1002 Class : Groups : radiusd Home : /nonexistent Shell : /usr/sbin/nologin Locked : yes OK? (yes/no): y adduser: INFO: Successfully added (radiusd) to the user database. adduser: INFO: Password for (radiusd) is: blablabla123 adduser: INFO: Account (radiusd) is locked. now edit %%PREFIX%%/etc/raddb/radiusd.conf uncomment & change the user & group entries from #user = nobody to user = radiusd #group = nobody to group = radiusd & change proxy_requests = yes to no now create the log files freeRADIUS will use in /var/log mkdir /var/log/radacct touch /var/log/radius.log touch /var/log/radutmp touch /var/log/radwtmp assign them right permissions chmod 700 /var/log/radacct chmod 644 /var/log/radius.log chmod 600 /var/log/radutmp chmod 644 /var/log/radwtmp then change their ownership chown radiusd:radiusd /var/log/radacct chown radiusd:radiusd /var/log/radius.log chown radiusd:radiusd /var/log/radutmp chown radiusd:radiusd /var/log/radwtmp 10) Now fireup freeRADIUS in debug mode by issuing %%PREFIX%%/sbin/radiusd -X & using the radtest tool query freeRADIUS radtest steve testing localhost 1812 s3cr3t you should get the following output back: Sending Access-Request of id 57 to 127.0.0.1 port 1812 User-Name = "steve" User-Password = "testing" NAS-IP-Address = 255.255.255.255 NAS-Port = 1812 rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=57, length=74 Class = 0x30373032333435363738 Session-Timeout = 3600 Idle-Timeout = 600 Acct-Interim-Interval = 60 WISPr-Bandwidth-Max-Up = 128000 WISPr-Bandwidth-Max-Down = 512000 if you're not sure if freeRADIUS is listening on port 1812/udp or 1645/udp check your /etc/services file $ cat /etc/services | grep radius # IMPORTANT NOTE: Ports 1645/1646 are the traditional radius ports used by #radius 1645/udp #RADIUS authentication protocol (old) radius 1812/udp #RADIUS authentication protocol (IANA sanctioned) If everything went along ok without any errors edit users & remove the entries you added from chillispots freeradius.users files. 11) Configuring freeRADIUS to use MySQL instead of flat files edit %%PREFIX%%/etc/raddb/sql.conf & change the login, password & radius_db entries to those used in step 6 then uncomment #sql_user_name = "%{Stripped-User-Name:-%{User-Name:-DEFAULT}}" & comment out sql_user_name = "%{User-Name}" if you'd like to use shortames (username minus realm) aswell as user@realm.f00 & :-DEFAULT then uncomment simul_count_query edit %%PREFIX%%/etc/raddb/radiusd.conf then uncomment sql in the Authorize { comment out unix in Authenticate { comment out files in preacct { uncomment sql in accounting { comment radutmp & uncomment sql in session { freeRADIUS is now setup to use MySQL. 12) You now need to setup some users for your wireless clients to use 12.1: login to the mysql console: mysql -u dbusername -p 12.2: choose the database you created for freeRADIUS to work on mysql> use mydbname; 12.3: lets see what in here: mysql> show tables; +----------------------+ | Tables_in_mydbname | +----------------------+ | nas | | radacct | | radcheck | | radgroupcheck | | radgroupreply | | radpostauth | | radreply | | usergroup | +----------------------+ 8 rows in set (0.00 sec) 12.4: to see what fields you need to fill in isse: mysql> show columns from radcheck; +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | | PRI | NULL | auto_increment | | UserName | varchar(64) | | MUL | | | | Attribute | varchar(32) | | | | | | op | char(2) | | | == | | | Value | varchar(253) | | | | | +-----------+------------------+------+-----+---------+----------------+ 5 rows in set (0.01 sec) 12.5: lets add our first username: mysql> insert into radcheck (Username, Attribute, Value) VALUES ('fry', 'Password', 'walkingonsunshine'); Query OK, 1 row affected (0.00 sec) 12.6: is it there? mysql> select * from radcheck; +----+----------+-----------+----+-------------------+ | id | UserName | Attribute | op | Value | +----+----------+-----------+----+-------------------+ | 1 | fry | Password | == | walkingonsunshine | +----+----------+-----------+----+-------------------+ 1 row in set (0.00 sec) 12.7: assign the user to a group: mysql> show columns from usergroup; +-----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+ | UserName | varchar(64) | | MUL | | | | GroupName | varchar(64) | | | | | | priority | int(11) | | | 1 | | +-----------+-------------+------+-----+---------+-------+ 3 rows in set (0.01 sec) mysql> insert into usergroup (UserName, GroupName, Priority) VALUES ('fry', 'dynamic', 1); Query OK, 1 row affected (0.00 sec) mysql> select * from usergroup; +----------+-----------+----------+ | UserName | GroupName | priority | +----------+-----------+----------+ | fry | dynamic | 1 | +----------+-----------+----------+ 1 row in set (0.01 sec) 12.8) Authorization Type: mysql> show columns from radgroupcheck; +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | | PRI | NULL | auto_increment | | GroupName | varchar(64) | | MUL | | | | Attribute | varchar(32) | | | | | | op | char(2) | | | == | | | Value | varchar(253) | | | | | +-----------+------------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) mysql> insert into radgroupcheck (GroupName, Attribute, Value) VALUES ('dynamic', 'Auth-Type', 'Local'); Query OK, 1 row affected (0.00 sec) mysql> select * from radgroupcheck; +----+-----------+-----------+----+-------+ | id | GroupName | Attribute | op | Value | +----+-----------+-----------+----+-------+ | 1 | dynamic | Auth-Type | == | Local | +----+-----------+-----------+----+-------+ 1 row in set (0.00 sec) mysql> show columns from radgroupcheck; +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | | PRI | NULL | auto_increment | | GroupName | varchar(64) | | MUL | | | | Attribute | varchar(32) | | | | | | op | char(2) | | | == | | | Value | varchar(253) | | | | | +-----------+------------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) 12.9) User & Group Attribute settings User specific attributes: mysql> show columns from radreply; +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | | PRI | NULL | auto_increment | | UserName | varchar(64) | | MUL | | | | Attribute | varchar(32) | | | | | | op | char(2) | | | = | | | Value | varchar(253) | | | | | +-----------+------------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) mysql> insert into radreply (UserName, Attribute, Value) VALUES ('fry', 'Class', '0702345678'); Query OK, 1 row affected (0.01 sec) mysql> select * from radreply; +----+----------+-----------+----+------------+ | id | UserName | Attribute | op | Value | +----+----------+-----------+----+------------+ | 1 | fry | Class | = | 0702345678 | +----+----------+-----------+----+------------+ 1 row in set (0.00 sec) Group specific settings: mysql> show columns from radgroupreply; +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | | PRI | NULL | auto_increment | | GroupName | varchar(64) | | MUL | | | | Attribute | varchar(32) | | | | | | op | char(2) | | | = | | | Value | varchar(253) | | | | | +-----------+------------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) mysql> insert into radgroupreply (GroupName, Attribute, Value) VALUES ('dynamic', 'Session-Timeout', '3600'); Query OK, 1 row affected (0.00 sec) mysql> insert into radgroupreply (GroupName, Attribute, Value) VALUES ('dynamic', 'Idle-Timeout', '600'); Query OK, 1 row affected (0.00 sec) mysql> insert into radgroupreply (GroupName, Attribute, Value) VALUES ('dynamic', 'Acct-Interim-Interval', '60'); Query OK, 1 row affected (0.01 sec) mysql> insert into radgroupreply (GroupName, Attribute, Value) VALUES ('dynamic', 'WISPr-Redirection-URL', 'http://www.geeklan.co.uk'); Query OK, 1 row affected (0.00 sec) mysql> insert into radgroupreply (GroupName, Attribute, Value) VALUES ('dynamic', 'WISPr-Bandwidth-Max-Up', '128000'); Query OK, 1 row affected (0.01 sec) mysql> insert into radgroupreply (GroupName, Attribute, Value) VALUES ('dynamic', 'WISPr-Bandwidth-Max-Down', '512000'); Query OK, 1 row affected (0.01 sec) mysql> select * from radgroupreply; +----+-----------+--------------------------+----+--------------------------+ | id | GroupName | Attribute | op | Value | +----+-----------+--------------------------+----+--------------------------+ | 1 | dynamic | Session-Timeout | = | 3600 | | 2 | dynamic | Idle-Timeout | = | 600 | | 3 | dynamic | Acct-Interim-Interval | = | 60 | | 4 | dynamic | WISPr-Redirection-URL | = | http://www.geeklan.co.uk | | 5 | dynamic | WISPr-Bandwidth-Max-Up | = | 128000 | | 6 | dynamic | WISPr-Bandwidth-Max-Down | = | 512000 | +----+-----------+--------------------------+----+--------------------------+ 6 rows in set (0.00 sec) Test: %%PREFIX%%/bin/radtest fry walkingonsunshine localhost 1812 s3cr3t Sending Access-Request of id 250 to 127.0.0.1 port 1812 User-Name = "fry" User-Password = "walkingonsunshine" NAS-IP-Address = 255.255.255.255 NAS-Port = 1812 rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=250, length=106 Class = 0x30373032333435363738 Session-Timeout = 3600 Idle-Timeout = 600 Acct-Interim-Interval = 60 WISPr-Redirection-URL = "http://www.geeklan.co.uk" WISPr-Bandwidth-Max-Up = 128000 WISPr-Bandwidth-Max-Down = 512000 13) Nearly There edit %%PREFIX%%/etc/chilli.conf & change the dns1 & dns2 entries to your dns servers (note, if you're not running a dns server locally you'll need to uncomment uamanydns) change radiusserver1 & radiusserver2 to localhost set radiussecret to whatever you selected in step 9 e.g s3cr3t set dhcpif to your wifi card e.g ral0 change uamserver to https://192.168.182.1/cgi-bin/hotspotlogin.cgi (if you're not running a dns server locally, if you are use the fqdn) change the uamsecret to another value, then edit %%PREFIX%%/www/cgi-bin/hotspotlogin.cgi & add the same value to $uamsecret 14) Finishing Stage Edit /etc/pf.conf & make sure the $ext_if & $int_if are correct Edit /etc/rc.conf & add the following: chillispot_enable="YES" apache_enable="YES" radiusd_enale="YES" mysql_enable="YES" pf_enable="YES" # Enable PF (load module if required) pf_rules="/etc/pf.conf" # rules definition file for pf pf_flags="" # additional flags for pfctl startup pflog_enable="YES" # start pflogd(8) pflog_logfile="/var/log/pflog" # where pflogd should store the logfile pflog_flags="" # additional flags for pflogd startup gateway_enable="YES" & remove any IP addresses assigned to your wifi card this is enough for chilli to work: ifconfig_ral0="ssid chilli mediaopt hostap mode 11b" save & reboot or quit to back to the shell & run the following to get everything started %%PREFIX%%/etc/rc.d/chillispot start %%PREFIX%%/etc/rc.d/apache.sh start you'll be asked for the password that you assigned whilst generating the certs in the step 3 %%PREFIX%%/etc/rc.d/mysql-server start %%PREFIX%%/etc/rc.d/radiusd start pfctl -e pfctl -f /etc/pf.conf THE END!!! Original Sources for info: OpenBSD PF FAQ http://www.openbsd.org/faq/ The FreeBSD HandBook http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/index.html SB's very rough notes to FreeRadius and MySQL http://www.frontios.com/freeradius.html ONLamp Getting Started with FreeRADIUS http://www.onlamp.com/pub/a/onlamp/excerpt/radius_5/index1.html?page=1 TAASC MySQL Basics http://www.analysisandsolutions.com/code/mybasic.htm This work is licensed under the Creative Commons Attribution-Share Alike 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.