=====Setting up a captive portal from scratch using Debian===== ===== Introduction ===== The following pages detail the installation of a Debian based operating system to do the following: * Share an internet connection to a number of users * Force people to sign up via a webpage before access is granted (with optional token system) * Traffic shape, so that P2P is given minimal bandwidth and web browsing is given priority * Display splash page periodically for advertising * Log all web browsing with Squid proxy server * Internet access is provided through an Alcatel speedtouch modem or a Solos ADSL2+ PCI card Although all the steps are shown to achieve this, they are not all explained in depth. This is more of a reminder to me so that a reinstall can be performed! If you do have any questions, please email me. The following assumptions are made: * Subnet of the network is 10.0.0.0/16 * Domain is called 'wardroom' ===== Install Debian ===== ==== Initial install ==== The assumption of the install is that no internet connection is available. Therefore the following are required initially: * CD1 of the standalone Debian install (V6) * Speedtouch firmware files (see below - assuming a speedtouch modem is used) Install as follows: * Boot from CD * Select the options as appropriate * Set up manual networking, using 10.0.0.1 for all the IP addresses and 255.255.0.0 as the network mask. * For this example the hostname will be called qualso * For this example the domain will be called wardroom ==== Partitioning ==== Set up partitioning as required. I used automatic partitioning. ==== Remaining system installation ==== * Let system install base software * Enter root password as required * When prompted create new user 'user' with required password * Select No to the option to scan another CD/DVD * Select No to use a network mirror for packages * Select No to package usage survey * Install Debian with web, DNS, SSH server and Standard packages * Select 'yes' to install GRUB to master boot record * Installation should now be finished. Take CD out and reboot into new system. ===== Setup the internet connection ===== We setup the internet connection now so that we can download further packages. ==== Using a Solos PCI ADSL internal modem ==== The Solos PCI drivers are bundled with recent kernel versions. I have previously had problems with the bundled versions and had to install from source. However, as of Squeeze they work out of the box. * Install PPP using the command apt-get install ppp * Create file /etc/ppp/chap-secrets with the following contents: ''%%"username@isp"%%'' ''%%"*"%%'' ''%%"password"%%'' Replace username and password as appropriate * Create file /etc/ppp/peers/isp0 with the following contents: noipdefault defaultroute user username@isp noauth updetach usepeerdns plugin pppoatm.so 0.0.38 Replace username as appropriate ==== Using a Speedtouch modem ==== * Install the ADSL Speedtouch modem firmware. Full details are [[http://www.linux-usb.org/SpeedTouch/|here]] but you should just be able to copy the 2 firmware files into /lib/firmware. For ease, both files are located at: http://files.andybev.com/web-portal/speedtouch1/speedtch-1.bin http://files.andybev.com/web-portal/speedtouch1/speedtch-2.bin Alternatively, these firmware files may work (for other versions): http://files.andybev.com/web-portal/speedtouch2/speedtch-1.bin http://files.andybev.com/web-portal/speedtouch2/speedtch-2.bin Obviously you will need to download these on another PC if you do not currently have internet on the current server. * Install PPP using the command apt-get install ppp Create file /etc/ppp/chap-secrets with the following contents: ''%%"username@isp"%%'' ''%%"*"%%'' ''%%"password"%%'' Replace username and password as appropriate Create file /etc/ppp/peers/isp0 with the following contents: noipdefault defaultroute user username@isp noauth updetach usepeerdns plugin pppoatm.so 0.38 Replace username as appropriate Disconnect and reconnect the USB modem to force it to load the firmware. Once the modem has synced, connect as below. ==== Temporarily connect to the internet ==== Connect to the internet using ''%%pppd%%'' ''%%call%%'' ''%%isp0%%'' This will be set to happen automatically later. ===== Further packages to install ===== A number of additional packages are needed and can be installed using apt. Because the installation was initially done from a CD, no network repositories will be available, so it is best to set one up using the netselect command. However, netselect is not currently installed and is not on the CD! So, setup a temporary network repository first: echo deb http://ftp.debian.org/debian squeeze main > /etc/apt/sources.list apt-get update Then install netselect-apt: apt-get install netselect-apt And finally use netselect to setup the best repositories: cd /etc/apt netselect-apt squeeze apt-get update * Now install additional packages using the command: ''%%apt-get install conntrack iptraf joe sudo squid3 php5 mysql-server php5-mysql%%'' * Install the DHCP server (this will fail to start after installation): ''%%apt-get install dhcp3-server%%'' Restart apache to load PHP (''%%apache2ctl%%'' ''%%restart%%'') * Edit /etc/apt/sources.list and uncomment the security updates line at the end ===== Set up ethernet IP address ===== * Edit /etc/network/interfaces * Ensure the eth0 entry looks as follows: auto eth0 iface eth0 inet static address 10.0.0.1 netmask 255.255.0.0 * If required set up a second ethernet interface. This can be used to provide internet access for a separate independent network if required. Add the following code to /etc/network/interface: auto eth1 iface eth1 inet static address 192.168.0.1 netmask 255.255.255.0 * Restart networking: /etc/init.d/networking restart ===== Update config files ===== Whenever told to edit files from this point use the Joe editor started with the command "joe " * Set up web server for captive portal (apache). The following instructions download all the files from this website. They can be edited as required, or alternatively full instructions for this method of setting up a captive portal are detailed elsewhere on this site. cd /var/ wget files.andybev.com/web-portal/portalshaper-www.tar.gz tar -zxvf portalshaper-www.tar.gz rm portalshaper-www.tar.gz - Edit settings.php and set all variables at beginning of the file as required, including the passwords - Edit key.php and add your own random key - Create blank database: - ''%%echo%%'' ''%%create%%'' ''%%database%%'' ''%%portal%%'' ''%%|%%'' ''%%mysql%%'' ''%%-p%%'' - ''%%mysql%%'' ''%%-p%%'' ''%%portal%%'' ''%%<%%'' ''%%portal-schema.sql%%'' - Setup mysql user (using password chosen in settings.php) - ''%%echo%%'' ''%%grant%%'' ''%%INSERT,UPDATE,DELETE,SELECT,LOCK%%'' ''%%TABLES%%'' ''%%on%%'' ''%%portal.*%%'' ''%%to%%'' ''%%'portal'@'localhost'%%'' ''%%identified%%'' ''%%by%%'' ''%%\'%%''''%%\'|mysql%%'' ''%%-p%%'' - You may also want to manually configure the hostname in /etc/apache2/apache2.conf by using the ServerName directive. * Configure URL redirect for captive portal by enabling mod_rewrite: cd /etc/apache2/mods-enabled ln -s ../mods-available/rewrite.load * Edit /etc/apache2/sites-enabled/000-default and add rewrite rules after ServerAdmin (be sure to edit server name qualso and add any other webserver names): Options +FollowSymlinks RewriteEngine On RewriteCond %{HTTP_HOST} !^qualso [NC] RewriteCond %{HTTP_HOST} !^earth [NC] RewriteRule . http://qualso.wardroom/index.php/%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING} [L,R] * Restart Apache: ''%%apache2ctl%%'' ''%%restart%%'' * Set up DNS server The DNS server is used to serve domain names of the local network and can also be used as a caching nameserver. * Edit /etc/bind/named.conf.local * Add the following after the "localhost" domain: zone "wardroom" { type master; file "/etc/bind/db.wardroom"; }; * Go to /etc/bind * Copy db.local to db.wardroom * Edit db.wardroom * Add required hostnames at the end of the file. These entries setup 3 different names for the main server (spaces should be tabs, and make sure that you increase the serial number). qualso is the name you gave your server earlier, earth is the name of the server as assumed by the web server and the captive portal web scripts. qualso A 10.0.0.1 earth A 10.0.0.1 mail A 10.0.0.1 * Reload BIND with ''%%/etc/init.d/bind9%%'' ''%%reload%%'' * Set up DHCP server for serving IP addresses to the local network: - Edit /etc/dhcp/dhcpd.conf: - Uncomment ''%%authoritative%%'' - Change ''%%option%%'' ''%%domain-name%%'' to wardroom - Change ''%%option%%'' ''%%domain-name-servers%%'' to 10.0.0.1 - Add ''%%allow%%'' ''%%booting;%%'' and ''%%allow%%'' ''%%bootp;%%'' after the above lines (only if using network boot clients - see later) - Add the following at the end of the file: subnet 10.0.0.0 netmask 255.255.0.0 { option subnet-mask 255.255.0.0; range 10.0.10.0 10.0.30.255; option broadcast-address 10.0.255.255; option routers 10.0.0.1; option root-path "10.0.0.1:/opt/ubuntu"; filename "pxelinux.0"; next-server 10.0.0.1; } The last 3 lines are only for network booting of clients. On a separate page (see link later) it is shown how to set up some network booting deskstations that will boot a network live copy of Ubunutu. Restart the DHCP server: /etc/init.d/isc-dhcp-server restart ===== Install IPSet ===== IPSet is a program that allows sets of IP addresses to be stored within iptables rules. It is used to collate a list of clients using P2P software. IPSet consists of both a kernel module and a userspace program. The module is not yet in the kernel provided with Debian. The following will install both the userspace program and the kernel module. aptitude install ipset ipset-source module-assistant module-assistant auto-install ipset-source ===== Install specialist internet scripts ===== These are a variety of scripts to do traffic shaping, force users to log on, and check that the PPP link is up. Full details are available on other pages of this Wiki. * This program removes cached tracks from the tracking table for a particular client. When a client is registered or unregistered from the network, this makes sure the correct web pages are presented on browsing the internet, otherwise any redirects are not properly flushed. cd /usr/local/bin wget http://files.andybev.com/web-portal/rmtrack chmod +x rmtrack * The following checks that the PPP link is up and reconnects if it is not cd /usr/local/bin wget http://files.andybev.com/web-portal/test-ppp chmod +x test-ppp cd /etc/init.d wget http://files.andybev.com/web-portal/test-ppp.init chmod +x test-ppp.init insserv test-ppp.init * The next 3 show the current internet bandwidth use in classes cd /usr/local/bin wget http://files.andybev.com/web-portal/linkstats-ppp0 chmod +x linkstats-ppp0 wget http://files.andybev.com/web-portal/linkstats-eth0 chmod +x linkstats-eth0 wget http://files.andybev.com/web-portal/tc-viewer chmod +x tc-viewer * And finally the firewall which sets up all the required iptables rules including the captive portal and shaping. This downloads the scripts and forces them to run when the network is brought up. cd /usr/local/ wget http://files.andybev.com/web-portal/portalshaper-sh.tar.gz tar -zxvf portalshaper-sh.tar.gz rm portalshaper-sh.tar.gz * Edit ''%%/usr/local/portal/settings%%'' as required The scripts within /usr/local/portal can be edited as required. Load balancing is enabled by default, but will obviously make no difference for only one interface. * If using a second ADSL line, create a new file in /etc/ppp/peers editing as required. The following is an example: ''%%noipdefault%%''\\ ''%%nodefaultroute%%''\\ ''%%user cwdwardroom1@cwlogin.adsl24.co.uk%%''\\ ''%%noauth%%''\\ ''%%updetach%%''\\ ''%%plugin pppoatm.so%%''\\ ''%%1.0.38%%'' * Add the associated entry into /etc/ppp/chap-secrets * Create a routing table for each interface (2 in this case): ''%%echo '101     balance1' >> /etc/iproute2/rt_tables%%''\\ ''%%echo '102     balance2' >> /etc/iproute2/rt_tables%%'' The following are some further optional examples: * To add a second independent ethernet interface: Use the script at http://files.andybev.com/web-portal/mess-office And add it to the "master" script just after the captive-portal entry ===== Connecting automatically using /etc/network/interfaces ===== * Edit /etc/network/interfaces adding the following: auto ppp0 iface ppp0 inet ppp pre-up /etc/network/solos-preload solos-pci0 provider isp0 post-up /usr/local/portalshaper/master * If using a second interface add it as well: auto ppp1 iface ppp1 inet ppp pre-up /etc/network/solos-preload solos-pci1 provider isp1 post-up /usr/local/portalshaper/master * Add pre-connection helper script (will need editing if using a speedtouch modem): cd /etc/network/ wget http://files.andybev.com/web-portal/solos-preload chmod +x solos-preload * Disconnect the current connection: ''%%killall%%'' ''%%pppd%%'' * Connect using ifup: ''%%ifup%%'' ''%%ppp0%%'' ===== Update sudoers file ===== * Run ''%%visudo%%'' and add the following lines. Sudo is used to allow the apache web server to add and remove the needed iptables rules each time a user signs up to access the internet, as well as update the Squid session helper when displaying announcement pages www-data ALL = NOPASSWD: /sbin/iptables -I internet 1 -t nat -m time --datestop ??????????????????? -m mac --mac-source ??\:??\:??\:??\:??\:?? -j RETURN www-data ALL = NOPASSWD: /sbin/iptables -D internet -t nat -m time --datestop ??????????????????? -m mac --mac-source ??\:??\:??\:??\:??\:?? -j RETURN www-data ALL = NOPASSWD: /usr/local/bin/rmtrack [0-9]*.[0-9]*.[0-9]*.[0-9]* www-data ALL = (proxy) NOPASSWD: /usr/lib/squid3/ext_session_acl Note: sudo does not use regular expressions, so the last statement is not as accurate as it should be ===== Configure Squid ===== |\\ Squid is configured to show splash page announcements and mark packets for traffic shaping. Both of these require recent patches which are only contained in the latest beta version of Squid. Therefore, a very recent version of Squid will need to be compiled and installed over the standard Debian build\\ \\ >| The web proxy is used to speed up requests, as well as log all requests and show a splash page periodically. * Edit /etc/squid3/squid.conf * Add the following to the beginning of the file: # We don't want persistent connections, otherwise lots # of requests to the same server will look like a bulk download server_persistent_connections off # Add a "fake" mark. This will stop packets being routed # incorrectly, at the early routing stages. They will be # properly routed at the re-route stage. qos_flows mark miss=0x1000000/0xF000000 * Change "http_port 3128" to "http_port 3128 transparent" * Comment out the following lines if upgrading from v3.1: ''%%acl manager proto cache_object%%''\\ ''%%acl localhost src 127.0.0.1/32 ::1%%''\\ ''%%acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1%%'' * Locate the section "INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS" and add the following rules (replacing qualso as required): acl our_networks src 10.0.0.0/16 # This ACL will only allow active sessions. Sessions are made active with separate # PHP code within the announce.php splash page external_acl_type session_active_def concurrency=100 ttl=3 %SRC /usr/lib/squid3/ext_session_acl -a -T 10800 -b /var/lib/squid/session/ acl session_is_active external session_active_def external_acl_type session_day_def ttl=60 %SRC /usr/lib/squid3/datetime_acl.pl /var/www/announce_days.txt acl session_day external session_day_def acl images urlpath_regex -i (\.gif$|\.jpg$|\.png$|\.jpeg$) deny_info http://qualso.wardroom/announce.php?url=%u session_day session_is_active images http_access deny session_day !session_is_active !images http_access allow our_networks * Create a session database. This is used to display the splash pages periodically. The associated /var/www/announce_days.txt file should be created when the web files are installed. mkdir -p /var/lib/squid/session chown proxy:proxy /var/lib/squid/session/ * Install the date/time external ACL helper: ''%%cd /usr/lib/squid3/%%''\\ ''%%wget %%''[[http://files.andybev.com/web-portal/datetime_acl.pl|''%%http://files.andybev.com/web-portal/datetime_acl.pl%%'']]\\ ''%%chmod +x datetime_acl.pl%%'' * Restart squid with ''%%/etc/init.d/squid3%%'' ''%%restart%%'' ===== Set up a software RAID (optional) ===== If you have 2 hard drives, use the steps in the following website to set up a software RAID: http://www.howtoforge.com/how-to-set-up-software-raid1-on-a-running-system-incl-grub2-configuration-debian-squeeze ===== Set up a USB memory stick for MYSQL backup (optional) ===== * Install autofs: ''%%apt-get install autofs udev%%'' * Create a mount area: ''%%mkdir /mnt/usb%%'' * Plug the USB memory stick in and find its UUID: ''%%udevadm info --query all --path /sys/block/sdc/sdc1/ |grep UUID%%'' * Edit /etc/auto.master and add: ''%%/mnt/usb   /etc/auto.removable --timeout=2,sync,nodev,nosuid%%'' * Create the file /etc/auto.removable and add (replacing UUID): ''%%backupusb             -fstype=auto       UUID=c9a095d8-c867-496b-98d4-d09c5c7f109f%%'' * Restart autofs: ''%%/etc/init.d/autofs restart%%'' Whenever the USB stick is pugged in, it will be mounted in /mnt/usb/backupusb * Create the file /root/backup.cnf for the mysql loging details: ''%%[client]%%''\\ ''%%user=portal%%''\\ ''%%password=%%'' * Run ''%%crontab%%'' ''%%-e%%'' and add the following line: ''%%0 12 * * * /usr/bin/mysqldump --defaults-extra-file=/root/backup.cnf --lock-tables portal > /mnt/usb/backupusb/portal-`/bin/date +\%a`.sql%%'' ===== Set up a local mail server to forward mail through using Postfix and ISP smarthost (optional) ===== Performing this step allows any user on the network to send mail through the server. By creating the setup shown below, any user wishing to send mail from their PC on the network will have to set up their mail client to authenticate with the server before they can send. The setup as shown will configure postfix as a smarthost, sending email to the ISP's mail server. This is preferable to sending email directly, as it is fairly likely that the IP address of the ADSL connection will be blacklisted. * ''%%apt-get%%'' ''%%install%%'' ''%%postfix%%'' (this will remove Exim) * When prompted, select "Internet with smarthost" * Enter the FQDN of the server (eg. qualso.wardroom) * Enter the server name of the ISP to relay mail through * Install the SASL libraries: ''%%apt-get%%'' ''%%install%%'' ''%%libsasl2-modules%%'' * Create a file /etc/postfix/relay_passwd with the following contents, replacing values as required: isp.server.name USERNAME:PASSWORD * Change the permissions on the file: chown root:root /etc/postfix/relay_passwd chmod 600 /etc/postfix/relay_passwd * Setup the files hash: postmap /etc/postfix/relay_passwd * Edit /etc/postfix/main.cf and add the following lines below the relayhost option: smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/relay_passwd smtp_sasl_security_options = * Edit /etc/mailname and set a valid FQDN (eg. qualso.simplelists.com). This will be the default mail domain for mail sent from the server. * If you want to allow local network users to send email without authentication, then just edit /etc/postfix/main.cf and add ''%%10.0.0.0/16%%'' to the "mynetworks" configuration line If you want to force people to authenticate, then: * Add a linux local user to the system with appropriate password. Users will use this account to authenticate against the SMTP server: useradd -g users mailuser passwd mailuser * After adding the user edit /etc/passwd and add ''%%/bin/false%%'' on the end of the line for the new user. This will stop people logging into the server using that username and password! * Setup SASL authentication using the steps detailed at [[SMTP_authentication_and_Postfix|SMTP authentication and Postfix]] ===== In use ===== * Any user connecting to the Internet will be presented with a sign up page before given access * Bandwidth stats can be viewed with either the commands ''%%iptraf%%'' or ''%%linkstats%%'' * Users and splash pages can be managed using http://qualso.wardroom/admin.php ===== Setting up network bootable live deskstations for internet browsing ===== The page [[Cubuntu|here]] shows how to set up an image on the server for any deskstation to network boot from. The great advantage of this is that each time a user has used the deskstation in question, the PC can be rebooted and the operating system will effectively be 're-installed'. Very low maintenance! Each time a user closes the firefox web browser, they will be presented with a single-click 'I agree to the terms and conditions' screen.