Components involved


Replication of production setup

Here, we replicate the relevant parts of the present installation as a starting point.

Base virtual machine preparation

Imported ~/Documents/Debian9-base.ova into Virtual Box as Debian9-base_8021x, re-initializing all MAC addresses. The description for this virtual machine template is:

Debian 9 amd64 installation
- Hostname:
- User accounts (username password):
ls last
root last
- Partitioning:
--- Physical:
------ 1GB RAID boot flag
------ 29GB RAID
--- RAID:
------ md0: ext3 /boot
------ md1: LVM - part of volume group debian9-base
--- LVM (VG/LV):
------ debian9-base/root: 18.6GB ext4 /
------ debian9-base/swap: 3.72GB swap area
- Up to date as of 2017-09-27
- sources.list includes:
Sections: main contrib non-free
Additional repository: backports
- Apt-cacher configured as per Last School site (Proxy credentials will need to be entered in /etc/apt/apt.conf.d/02proxy by user)
- SSH access installed and enabled

- Gnome and Firefox configured to auto-detect proxy settings
- Extra software installed:
vlc gimp emacs fonts-indic tcpdump iperf exfat-utils wireshark

- One network interface as bridged adapter, cable connected.

Added a second ethernet adapter in settings, connected to "Not attached", re-initialized its MAC address
Increased the allocated CPUs to 2

The network configuration is now as follows:

enp0s3 - Adapter 1 - Bridged adapter

enp0s8 - Adapter 2 - Not attached

Booted, disconnected eth2 because of errors

Logged in to GUI, connected DHCP

rm /etc/apt/apt.conf.d/02proxy
apt-get update
apt-get upgrade

Rebooted the virtual machine

Set strong passwords for ls and root users

Installed my ssh public key in root's .ssh/authorized_keys file.


Installation of relevant services:

Shorewall (based on LASTSCHL-207):


apt-get install shorewall
apt-get install ipset
mv /etc/shorewall{,-orig}
mkdir /etc/shorewall
root@debian9-base:/etc/shorewall# for i in `ls`; do echo "========= $i ========="; cat $i | grep -v "^#" | grep -v "^$"; echo "========= $i ========="; echo ""; done
========= hosts =========
========= hosts =========

========= interfaces =========
net     enp0s3         detect      tcpflags,dhcp,nosmurfs,routefilter,logmartians
wifi	enp0s8		   detect	   tcpflags,nosmurfs,routefilter,logmartians
========= interfaces =========

========= masq =========
========= masq =========

========= policy =========
$FW		net		REJECT		INFO(uid)
$FW		wifi	ACCEPT		INFO(uid)
wifi	all		REJECT
net		all		DROP		INFO
all		all		REJECT		info
========= policy =========

========= routestopped =========
========= routestopped =========

========= rules =========
Invalid(DROP)		 net			 all
ACCEPT:INFO(uid)     net             $FW             tcp     22
ACCEPT:INFO(uid)     net             $FW             udp     123
ACCEPT:INFO(uid)     net	     	 $FW	     	 icmp
ACCEPT:INFO(uid)     $FW             net             tcp     465,587,995,993
ACCEPT:INFO(uid)     $FW             net             udp     53,123
ACCEPT:INFO(uid)     $FW	     	 net	     	 icmp
ACCEPT:INFO(uid)     $FW             net             tcp     -            -               -               -               root
ACCEPT:INFO(uid)     $FW             net             udp     -            -               -               -               root
ACCEPT:INFO(uid)     $FW             net             icmp    -            -               -               -               root
ACCEPT:INFO(uid)     $FW             net             tcp     -            -               -               -               _apt
ACCEPT:INFO(uid)     $FW             net             udp     -            -               -               -               _apt
ACCEPT:INFO(uid)     $FW             net             icmp    -            -               -               -               _apt
========= rules =========

========= shorewall.conf =========
========= shorewall.conf =========

========= zones =========
fw			firewall
net			ipv4
wifi		ipv4
========= zones =========

In /etc/default/shorewall, set

root@server.lastschl:~# scp /etc/rsyslog.d/40-shorewall.conf
root@server.lastschl:~# scp /etc/logrotate.d/shorewall
root@server.lastschl:~# scp /etc/logrotate.d/rsyslog
root@server.lastschl:~# scp /etc/logrotate.conf

systemctl enable shorewall.service

Configure network and DHCP (based on LASTSCHL-212):

systemctl disable network-manager.service
systemctl disable NetworkManager.service


# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The external interface
auto enp0s3
iface enp0s3 inet static
# The wifi interface
auto enp0s8
iface enp0s8 inet static
unlink /etc/resolv.conf
echo nameserver > /etc/resolv.conf
mkdir /etc/ltsp
root@server.lastschl:~# scp /etc/dhcp/dhcpd.conf



# Default LTSP dhcpd.conf config file.


subnet netmask {
    option domain-name "test.av";
    option domain-name-servers;
    option broadcast-address;
    option routers;
    option subnet-mask;
    option root-path "/opt/ltsp/amd64";
    if substring( option vendor-class-identifier, 0, 9 ) = "PXEClient" {
        filename "/ltsp/amd64/pxelinux.0";
    } else {
        filename "/ltsp/amd64/nbi.img";




In /etc/default/isc-dhcp-server, set:

apt-get install isc-dhcp-server




Configure DNS (based on LASTSCHL-211):

apt-get install dnsmasq
touch /var/log/dnsmasq
chmod 640 /var/log/dnsmasqSet in /etc/dnsmasq.conf

	rotate 730
		reload rsyslog >/dev/null 2>&1 || true



/etc/hosts	localhost	test.av	server.test.av	server

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters


New stuff


Added to /etc/shorewall/hosts:

wifi1 enp0s8:dynamic

added to policy:
wifi1 net ACCEPT INFO
wifi1 $FW ACCEPT INFO(uid)
$FW wifi1 ACCEPT INFO(uid)
Added to /etc/shorewall/zones:

wifi1:wifi ipv4 dynamic_shared

In shorewall.conf set:



packages: freeradius

Modified /etc/freeradius/3.0/mods-available/eap:

commented the following:

#       md5 {
#       }
#       leap {
#       }
#       gtc {
#               #  The default challenge, which many clients
#               #  ignore..
#               #challenge = "Password: "
#               #  The plain-text response which comes back
#               #  is put into a User-Password attribute,
#               #  and passed to another module for
#       	#  authentication.  This allows the EAP-GTC
#               #  response to be checked against plain-text,
#               #  or crypt'd passwords.
#               #
#               #  If you say "Local" instead of "PAP", then
#       	#  the module will look for a User-Password
#               #  configured for the request, and do the
#               #  authentication itself.
#               #
#               auth_type = PAP
#       }
#       tls {
#               # Point to the common TLS configuration
#               tls = tls-common
#       	#
#               # As part of checking a client certificate, the EAP-TLS
#               # sets some attributes such as TLS-Client-Cert-CN. This
#               # virtual server has access to these attributes, and can
#               # be used to accept or reject the request.
#       	#
#       #       virtual_server = check-eap-tls
#       }

modified the 'default_eap_type' directive under section 'eap' to be:

default_eap_type = peap

and the 'default_eap_type' directive under section 'ttls' to be:

default_eap_type = mschapv2

Modify /etc/freeradius/3.0/clients.conf, comment the 'client localhost' and 'client localhost_ipv6' section and add a few of these blocks at the end, one for each wifi router:

client test1 { # Replace test1 with a name for the router
       ipaddr = # Replace with IP of the router
       secret = password # Replace with an actual password



as freerad?

Modified /etc/freeradius/3.0/certs/ca.cnf, set the following settings:

[ req ]
input_password	= password # Replace with an actual password
output_password	= password # Replace with an actual password

countryName	= IN
stateOrProvinceName	= Tamil Nadu
localityName	= Auroville
organizationName	= Test
emailAddress	= admin@test.av
commonName	= "Test Certificate Authority"

Modified /etc/freeradius/3.0/certs/server.cnf, set the following settings:

[ CA_default ]
crlDistributionPoints	= URI:http://server.test.av/test_ca.crl

[ req ]
input_password	= password # Replace with an actual password
output_password	= password # Replace with an actual password

countryName	= IN
stateOrProvinceName	= Tamil Nadu
localityName	= Auroville
organizationName	= Test
emailAddress	= admin@test.av
commonName	= "Test Server Certificate"
crlDistributionPoints	= URI:http://server.test.av/test_ca.crl

as freerad ("@@@" right way to do it?):

cd /etc/freeradius/3.0/certs

Modify /etc/freeradius/3.0/mods-available/eap, modify the following directives under section 'tls-config tls-common' to be:

private_key_password = password # Replace password with the password chosen previously
private_key_file = /etc/freeradius/3.0/certs/server.pem
certificate_file = /etc/freeradius/3.0/certs/server.pem
ca_file = /etc/freeradius/3.0/certs/ca.pem



apt-get install mysql-server
mysql -uroot
mysql -uroot radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql

Edit /etc/freeradius/3.0/mods-config/sql/main/mysql/setup.sql. Modify the following lines:

CREATE USER 'radius'@'localhost';
SET PASSWORD FOR 'radius'@'localhost' = PASSWORD('radpass');


CREATE USER 'freerad'@'localhost' IDENTIFIED VIA unix_socket;

and update the username 'radius' to be 'freerad' wherever else it is mentioned in the file.

mysql -uroot radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/setup.sql
cd /etc/freeradius/3.0/mods-enabled
ln -s ../mods-available/sql sql

In /etc/freeradius/3.0/mods-enabled/sql, set the following options:

driver = "rlm_sql_mysql"
dialect = "mysql"
server = "localhost"
port = 3306
login = "freerad"
password = ""
radius_db = "radius"
logfile = ${logdir}/sqllog.sql # Do we need this?

Modify /etc/freeradius/3.0/sites-enabled/inner-tunnel, find the following line under authorize, post-auth and Post-Auth-Type REJECT sections


modify it to


Modify /etc/freeradius/3.0/sites-enabled/default, find the following line under authorize, post-auth and Post-Auth-Type REJECT sections


In the post-auth and Post-Auth-Type REJECT sections, modify it to


In the authorize section, comment it out.


add to few places "@@@" review

Python module / script

cd /etc/freeradius/3.0/mods-enabled
ln -s ../mods-available/python python

Put the following in it:

# Make sure the PYTHONPATH environmental variable contains the
# directory(s) for the modules listed below.
# Uncomment any func_* which are included in your module. If
# rlm_python is called for a section which does not have
# a function defined, it will return NOOP.
python {
	module = script_launcher # @#$dy

	python_path = ${modconfdir}/${.:name}:/usr/lib/python2.7 # @#$dy
	mod_post_auth = ${.module} # @#$dy
	func_post_auth = post_auth # @#$dy

Modify /etc/freeradius/3.0/sites-enabled/inner-tunnel:

# Add this line just after 'sql' in the 'post-auth' section

Modify /etc/freeradius/3.0/mods-available/eap, modified the 'copy_request_to_tunnel' directive under both sections 'peap' and 'ttls' to be:


copy_request_to_tunnel = yes


Place the script at /etc/freeradius/3.0/mods-config/python/



packages: sudo

apt-get install sudo

Created /etc/sudoers.d/shwl_add, permissions 640 root:root, with:

freerad ALL=(root:root) NOPASSWD:/sbin/shorewall,/usr/bin/arp-scan


shwl_add / shwl_del scripts

 packages: arp-scan

apt-get install arp-scan
# Install the scripts in /usr/local/sbin/, and configure settings in each of them
chown root:freerad /usr/local/sbin/shwl_*
chmod 750 /usr/local/sbin/shwl_*
mkdir /var/local/shwl_add
chown freerad:freerad /var/local/shwl_add
chmod 700 /var/local/shwl_add
chmod a-s /var/local/shwl_add

Add the following line to freerad's crontab

*/1 * * * * /usr/local/sbin/ # @#$dy # @@@ figure out optimal interval



mysql -uroot
  CREATE DATABASE shwl_add_shwl_del_pmu;
  GRANT ALL on shwl_add_shwl_del_pmu.event_log TO 'radius'@'localhost';
mysql -uroot radius < shwl_add_shwl_del_pmu.sql script

Pre-requisites from above steps: sudo, shwl_add / shwl_del scripts MySQL config, FreeRADIUS MySQL config

apt-get install libpam-script sshpass
mkdir /usr/share/libpam-script/pam-script.d/pam_to_mysql_update
cd /usr/share/libpam-script/pam-script.d/pam_to_mysql_update
# Put the script in here, and configure MySQL settings inside
ln -s pam_script_auth
ln -s pam_script_passwd

Add the following line at the end of /etc/pam.d/common-auth or as may be appropriate to the PAM configuration of the system:

auth	required               onerr=fail dir=/usr/share/libpam-script/pam-script.d/pam_to_mysql_update/

Add the following line at the end of /etc/pam.d/common-password or as may be appropriate to the PAM configuration of the system:


password	required               onerr=fail dir=/usr/share/libpam-script/pam-script.d/pam_to_mysql_update/