Create a Raspberry Pi WiFi Relay

In this tutorial I am going to show you how to create a WiFi Relay using your Raspberry Pi. This will allow your Raspberry Pi to connect to a Wifi AP and then also broadcast it’s own WiFi, and route that traffic over the original WiFi AP.

Raspberry Pi Wifi Relay
Raspberry Pi Wifi Relay

So why would you want to do this?

So you may be wondering “Why would I want to relay wifi”, well there are lots of legitimate and admittedly illegitimate reasons for doing so. My purpose for making this myself was for a work reason. Our company issues us consultants with a 4G dongle (a ZTE MF821) per client site. The ZTE MF821 has wifi capabilities built in however it only allows for 5 connections at most at any time, which really doesn’t work when you’re working on a project that has a full compliment of staff working and needing internet access. So I needed a way to relay this internet connectivity on a new AP that didn’t have the limitation of 5 devices. And that’s my Raspberry Pi.

To make it an even cooler solution, I decided to impersonate the WiFi back at our head office. And because every consultant has the company WiFi already stored in our devices, as soon as a colleague walks onto client site, they are instantly connected. Very Cool!

So let’s begin!

What you will need to do this tutorial:

  • Raspberry Pi Model B+
    Raspberry Pi Model B+

    A Raspberry Pi (of course!)
    Either the Model B or B+ is perfect for the task, but don’t overclock it, it’s unnecessary for this task.

    TP-Link WN722N Adapters
    TP-Link WN722N Adapters
  • 2x WiFi adapters that are linux compatible
    I highly recommend using TP-Link WN722N, they are awesome adapters and compatible with nearly anything. However if you haven’t got one of these and need to find an adapter that will work, google “Kali WiFi Adapters” and you will find lists of highly compatible devices to buy.
  • Samsung 16GB Micro SD
    Samsung 16GB Micro SD

    A fresh Raspbian on a SD / Micro SD card ready to go!
    I will be using the Raspbian Wheezy 2014-09-09 release during this tutorial. Make sure you have completed the Raspbian config utility prior to starting this guide.

 

Assumptions:

This guide will assume that:

  • You have completed the Raspbian Setup Utility
  • You are connected to your raspberry Pi and can create a shell session either by eth0 or a console cable. Warning! if you connect via WiFi it could affect your ability to do this tutorial successfully.
    • We will be using nano as a editor in this tutorial, and putty as a shell. Vim people – don’t be haters 🙂 and mac users can use the ssh command in your terminal in lieu of having putty.
    • You have a working understanding of setting up a WiFi network using a retail piece of equipment.
    • You have a working understanding of basic network configuration (DHCP servers and clients, IP addressing, subnets and routing)
    • You have a working understanding of the basics of linux, such as editing files, traversing the file system and using basic applications.

Okay, let’s begin!

So the first thing we will do is make sure our Pi and it’s packages are updated:

apt-get update -y

Now we need to grab all the packages we will be using for this process:

apt-get install hostapd hostap-utils iw dnsmasq -y

Once this completes it’s time to setup our hosted AP.

Part 1 – Setup the Raspberry Pi WiFi AP

Editing /etc/network/interfaces

The first thing we need to do is attach a wifi adapter to become wlan0, so go ahead and do it now. It may take up to 30 seconds for the devices to fully install and register. To see if this is completed keep running ‘iwconfig‘ until you see wlan0 appear.

Now we need to configure our new network. We will be using wlan0 for the Raspberry Pi’s WiFi AP and wlan1 later as the client of the existing WiFi AP. You can use a different IP Address range and subnet if you wish but we will be using 192.168.10.0 / 255.255.255.0 for this tutorial for our hosted AP and issued DHCP leases.

Let’s edit /etc/network/interfaces and setup the correct configuration for our adapter. We need to make sure that our wlan0 is configured with static ip addressing on the correct subnet rather than the default conf which is occasionally loaded by the OS (don’t panic if all you see is the first three lines of the screenshot, just append to the end of the file.) Start the editor by running the following command:

nano /etc/network/interfaces

Now remove the preexisting configurations in this file in reference to wlan0 and then append the following to the end of the file:

allow-hotplug wlan0
iface wlan0 inet static
 address 192.168.10.1
 netmask 255.255.255.0

Your file should now look like this:

a-interfaces-conf
This is how your /etc/network/interfaces file should look at this stage, we will be editing it more later!

Hit Ctrl+X and press Y to save and exit nano.

To confirm that your file is configured in a ‘sane’ way, lets bring down the adapter and put it back up again by running the following two commands:

ifconfig wlan0 down
ifconfig wlan0 up

If there is an error in our configuration then you will see output when you try to put the adapter back up. However I am sure yours will look just like mine does below:

If your conf is good, your output should be the same as the above
If your conf is good, your output should be the same as the above

 Configure DHCP – Editing /etc/dnsmasq.conf

OK now that our network adapter wlan0 is statically configured, we need to configure dnsmasq. The config file for this is HUGE! you will have to make use of the search in nano (Ctrl+W, type string to search for and hit enter. to repeat a search press Ctrl+W and then hit enter).

Edit /etc/dnsmasq.conf by running the below command:

nano /etc/dnsmasq.conf

The make the following adjustments:

  •  Search for #no-resolv, remove the leading # to uncomment this line

    Make sure your line looks like this
    Make sure your line looks like this
  • Search for #address= and change this line to be:
    address=/#/192.168.10.1

    Make sure your line looks like this
    Make sure your line looks like this
  • Search for #interface= and remove the leading hash to uncomment the line, and then add wlan0 after the = sign.

    Make sure your line looks like this
    Make sure your line looks like this
  • Search for #domain= remove the leading hash and then change it’s value to pifi.local (or whatever else you would like).

    Make sure your line looks like this
    Make sure your line looks like this
  • Search for #dhcp-range and remove the leading hash, then change the line to read:
    dhcp-range=192.168.10.50,192.168.10.150,255.255.255.0,2h

    Make sure your line looks like this
    Make sure your line looks like this

Hit Ctrl+X and press Y to save and exit nano.

That’s the worst part of the configuration sorted for this tutorial. The other config files are a lot easier to deal with I promise.

Configure hostapd – /etc/hostapd/hostapd.conf

OK now we need to configure our WiFi AP that our Raspberry Pi will be broadcasting for our clients to connect to.

Edit /etc/hostapd/hostapd.conf by running the following:

nano /etc/hostapd/hostapd.conf

Erasing anything that is pre-existing in this file, paste in the below configuration whilst changing the values for ssid and wpa_passphrase to whatever you like.

interface=wlan0
driver=nl80211
ssid=PiFi
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=MyPiFiPassword123
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

 Warning: You need to be extremely careful with the formatting of this file;

  • Wrap values with spaces in them with quotes “”
  • Ensure there is no leading or trailing white space on any line
  • Make sure there is no white space between the key=value elements
  • Make sure there are no blank / empty lines at the top or bottom of the file.

hostapd is very particular about what it likes to consume.

Once your config looks like the below….

Your hostapd file should look like this
Your hostapd file should look like this

Hit Ctrl+X and press Y to save and exit nano.

Now it’s time to test out our WiFi AP!

Run the following command to start hostapd and broadcasting your new AP.

/usr/sbin/hostapd /etc/hostapd/hostapd.conf

And you should see the following…

Your output should be similar to this
Your output should be similar to this
Your new PiFi should now be visible to devices
Your new PiFi should now be visible to devices

And if you check on a PC with wifi you will see your new WiFi AP being broadcasted!

If you now attempt to connect to the wireless AP using the credentials you set earlier then you should connect to the wifi, get a dchp lease and even be able to connect to your raspberry pi over it!

However for now we need to stop this wfi and continue with our configurations before we make it permanent, so go ahead and hit Ctrl+C to stop the wifi and regain control of your shell.

The last thing we will do is run a command to make sure that dnsmasq and hostapd will start at boot:

update-rc.d dnsmasq enable
update-rc.d hostapd enable

And you should see the following:

If your output looks like the above then dnsmasq and hostapd are all set to auto start when the pi boots!
If your output looks like the above then dnsmasq and hostapd are all set to auto start when the pi boots!

 Part 2 – Configure wlan1 to be a WiFi Client

Now you can connect your second WiFi adapter which will install and become wlan1, just as before you can keep running iwconfig until you see wlan1 come online.

Edit /etc/network/interfaces again

Open up /etc/network/interfaces using the following command:

nano /etc/network/interfaces

And below our settings for wlan0 with a empty line between for nice readability, enter the following configurations for wlan1

allow-hotplug wlan1
iface wlan1 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

Hit Ctrl+X and press Y to save and exit nano.

Configure wlan1’s WiFi client settings – Edit /etc/wpa_supplicant/wpa_supplicant.conf

Open up /etc/wpa_supplicant/wpa_supplicant.conf using the below command:

nano /etc/wpa_supplicant/wpa_supplicant.conf

When you open this file you will probably see  couple lines already populated, if so just edit the file to look like the below, otherwise paste the configuration below into the editor, and then change the settings as needed to the WiFi point you want wlan1 to be connected to.

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
  ssid="YOURSSID"
  psk="YOURPASSWORD"
  # Key management type can be: WPA-PSK or WPA-EAP (Pre-Shared or Enterprise)
  key_mgmt=WPA-PSK
}

Once you have updated the configuration to match the above / your personal WiFi setup hit Ctrl+X and then press Y to save and exit nano.

Now it’s time to reboot your device, when it starts up it should try to connect to the WiFi point you set in here, run the following command to restart the pi:

reboot

Once the pi starts up and you’re logged in again, you can confirm that the pi is connected to your WiFi on wlan1 by running the following command and looking at the data for wlan1:

iwconfig

You should see the following, just with your WiFi details:

Congrats! Your wifi client is now connected!
Congrats! Your wifi client is now connected!

 Routing traffic between wlan0 and wlan1

OK we now have a working WiFi AP on wlan0 which issues DHCP leases and we have a working WiFi client on wlan1 which can browse the other WiFi AP’s network (and presumably the internet). So now we need to rout traffic inbound to wlan0 to wlan1 and returning traffic from wlan1 to the requester on wlan0.

We do this in just two steps.

Enable IP Forwarding – /etc/sysctrl.conf

Open /etc/sysctrl.conf by running the below command:

nano /etc/sysctrl.conf

Search for “net.ipv4.ip_forward=” then remove the leading has symbol making sure your line looks like the below:

Make sure your line looks like the above.
Make sure your line looks like the above.

Hit Ctrl+X and press Y to save and exit nano.

And because we want to save ourselves a reboot we will hot activate it for this boot by running the following:

sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

Enter iptables rules to route traffic between the adapters wlan0 and wlan1

This is really simple, just send the following commands in the shell:

iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
iptables -A FORWARD -i wlan0 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wlan1 -o wlan0 -j ACCEPT

Then we will save these routes to file to be loaded again when the server boots.

sh -c "iptables-save > /etc/iptables.ipv4.nat"

Lastly we need to edit /etc/network/interfaces one last time to add a command that will load these iptables rules when the server boots.

Open /etc/network/interfaces using the below command:

nano /etc/network/interfaces

And at the very end of the file append the following:

iptables-restore < /etc/iptables.ipv4.nat

If your configuration now looks like the below….

Make sure your conf looks like the above, keeping in mind your personal customizations to the network addressing scheme / subnet
Make sure your conf looks like the above, keeping in mind your personal customizations to the network addressing scheme / subnet

Then press Ctrl+X and then press Y to save and exit nano.

 That’s it! You’re all done!

Congratulations, you made it if you reboot your pi when it starts you should see in about 1 minute your wifi AP appear and if you connect to it, you should be routed from wlan0 to wlan1 and out to the other WiFi AP.

In my introduction I mentioned that in my real world application of this setup I am pretending to be a WiFi AP in another location. To achieve this yourself all you need to do is configure your hostapd file (/etc/hostapd.conf) to the same settings as the original AP, then when devices walk in rage of your WiFi AP it will connect to it perfectly.

Where to now?

Well you could:

  • See if you can apply the above logic to create a WiFi AP for eth0.
  • Create a VPN client connection on your Raspberry Pi and route wlan0 out that effectively creating a secure VPN WiFi AP.
  • Test your dark side and sniff traffic going between wlan0 and wlan1 (for this use the Kali distro for Raspberry Pi as a base).
  • Create a mesh of roam-able WiFi points all around your house and in your back yard.
  • Write a comment below 🙂

Thanks for reading!

Xavier.

 

 

 

 

 

LAMP Server – Linux (CentOS) + Apache + MySQL + PHP Server setup

Okay, this one has been done a million times over, in fact at the time of writing if you were to type the search “LAMP guide” into Google you will get around 331,000,000 pages! So why would I bother writing about it again? Well everyone has their own flavor of doing a LAMP server, and mine is probably just like yours! However I will be referencing a LAMP as a base server in many other posts of mine so if someone (or you) were later to want to do one of them you could start off with the same base system as me in the tutorials!

Anyway let’s get to it shall we?

But wait! I’m lazy or I don’t care about how you setup LAMP I just want it!

Ahhh ok, if you have done this all before and just want a no hassle get it over with script, then just copy and paste the below into a bash session and you’re done, with the exception of Securing your MySQL installation:

yum install httpd php mysql-server mysql php-mysql -y
service httpd start
service mysqld start
echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php

However if you aren’t interested in learning about a LAMP setup, then that’s ok! Not everyone wants to be intimate with Linux, however I don’t feel that you should be running your own server without this knowledge, so why not use a web hosting service and let them take care of it for you? 🙂

What is a LAMP server

A LAMP server essentially means a server (virtual or dedicated) with a Linux based Operating System and the following packages installed:

  • Apache – The HTTP service, it’s what listens for requests for HTTP data and replies in kind
  • MySQL – The database product and dare I say the most common database solution for Linux based systems (that are not mission critical, even though MySQL is still a great product for that!)
  • PHP – The intelligence behind a lot of websites, it’s what runs logic and code before Apache goes and throws the requested data to a client’s machine (this is a very high level explanation of PHP and it’s not meant to offend!).

So why would I want one?

A LAMP server represents the most common but ‘basic’ webserver setup that is used to build upon. It will parse PHP script, reply to HTTP requests and the website can utilize a database storage system.

Ok, let’s get installing!

Prerequisites and assumptions

So during this tutorial I will be using a fresh installation of CentOS 6.5 x86 edition, different versions of CentOS and other flavors of Linux each have their own quirks, so see if you can follow, if you really get stuck try Google (only because its quicker than….) or post a comment and I will help you out as soon as I can!

For each of these steps we will be doing as the Linux user ‘root’ which gives us no hassle complete unrestricted use of the system. If you are not using root you should prefix all the bash commands with the following:

sudo

Installing all the packages

Ok we are going to install all the packages we need with a short and quick command:

yum install httpd php mysql-server mysql php-mysql -y

So what does this do?

  • yum – This is the package manager application, a bit like the “Add and Remove Programs” feature in Windows’s Control Panel
  • install – This let’s yum know what we are going to be doing (install, update or remove are most common)
  • httpd – This is the primary Apache package
  • php – This is the primary PHP package
  • mysql-server – This is the primary MySQL server package.
  • mysql – this is the primary MySQL client package
  • php-mysql – This is an extension for PHP that gives it the ability to perform actions with MySQL.
  • -y – This means don’t prompt us about y/n decisions regarding dependencies and download / install usage, just do it!

You should see it finish by summarizing the installed packages and dependencies and that will be the main installation done!

Making sure that Apache and MySQL start

We will issue a restart command to these services by executing the below bash commands:

service httpd start
service mysqld start

And then you should see 2 green OK messages like the below:

You will notice I have a warning message after my Apache and MySQL OK messages.

Don’t worry about the Apache one, the hostname I gave to my server when I created it doesn’t actually exist in the xaviertidus.com DNS, so Apache is warning us to take a look at that. In a real world situation we should definitely take care of this but as this is a demo for you we can just ignore it!

As for the MySQL warning, it’s valid because when MySQL is installed the root login doesn’t have a password, and it contains a bunch of permissions for a demo database which needs to be removed if you don’t plan to use it, but we will talk about that a little later on in the tutorial.

Securing your MySQL

Okay so your LAMP setup is almost complete however you need to secure your MySQL installation by running the following command:

/usr/bin/mysql_secure_installation

If you want to read more about this then check out another article I wrote all about securing MySQL post install here: Securing your new MySQL installation with /usr/bin/mysql_secure_installation

Testing your installation

Everything is done, however we should probably test it right?

The simplest way of doing this is creating a php info file, this is a file that contains only a single line of code (PHP code) and will display in a web browser all the information PHP has about your hosting environment. So let’s create one now, type the following in your shell:

echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php

Now you can view the page by browsing to it in your web browser, changing the ip address in my demo below to your server’s IP or hostname.

http://192.168.1.60/phpinfo.php

And  you should see something similar to the following:

And that’s it you’re done!

Having trouble seeing the phpinfo.php page?

I did too! Try just navigating to the server’s IP address or hostname, you should see something like this:

if you do, then the problem is probably in that php file we just created, edit using nano and see if you can fix the error or comment below for help.

If you cannot even see this page and your page request seems to time out after a long while then the problem is most likely that port 80 isn’t open.

To fix then edit the iptables file using the command below (I use nano which may not yet be installed, you can install it or use vi or whatever editor you like)

nano /etc/sysconfig/iptables

And we need to add the following line to your iptables file

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

The best place for it is just before the reject commands, so once you are finished it should look something like this:

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

Now we just need to restart iptables for the changes to take effect, we do this by running this command:

/etc/init.d/iptables restart

You should see green across the board like the below:

However if you see something like this:

Just make sure that your iptables file has no blank lines or lines that begin with spaces and that you copied the rule correctly from here. Then try restarting iptables again.

Now hopefully you should be able to access your server on port 80, you may have to repeat this process with port 445 as well if you intend on using SSL.

Enjoy!

 

 

Install FreeRadius on CentOS 5 or 6 in just 3 commands!

Inspired by my previous post here: How to install a PPTPD VPN server on Centos 6.X in just 4 commands I wanted to make an installer for FreeRadius that could be achieved in as little steps as PPTPD.

And here we go, FreeRadius in 3 steps (or 5 if you’re using CentOS 5).

What you will need for this tutorial

  1. A VPS with Centos 5.x or 6.x (32 or 64 bit is ok)
  2. About 2 minutes of free time! (yes it’s that quick!)
  3. Putty terminal already connected to your server, ready to go!

Need a VPS? I highly recommend DigitalOcean if you are shopping around, pretty quick support and their entire website is perfectly automated. It’s a very impressive place to hang out!

Let’s begin, and finish in one step!

Simply copy and paste the appropriate set of commands below for your OS version into your putty session:

CentOS 6:

yum install -y git
cd /opt && git clone git://github.com/xaviertidus/FreeRadiusQuickScript.git
cd FreeRadiusQuickScript && bash install.centos6.sh

CentOS 5:

wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.i386.rpm
rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
rpm -K rpmforge-release-0.5.2-2.el5.rf.i386.rpm
rpm -i rpmforge-release-0.5.2-2.el5.rf.i386.rpm
yum install -y git
cd /opt && git clone git://github.com/xaviertidus/FreeRadiusQuickScript.git
cd FreeRadiusQuickScript && bash install.centos5.sh

Once the final command from the lists above is input, my installer will start. It will ask you for two new passwords at the beginning, these are (in order of appearance):

Radius SQL User Password – this is the password that FreeRadius will use to connect to MySQL to verify logins sent to it for authorization.

Localhost Auth Request Secret – This is the secret that applications running on localhost will pass to FreeRadius to verify they are allowed to query.

Both of these have a default password set in the installer, so if you aren’t to bothered about security you can just hit enter for both of these without entering a thing.

Why does CentOS5 have a couple extra steps?

CentOS 5 was released back when Git was still a lil baby, and so it wasn’t in the repos for CentOS5. However we can add it in by using the few extra commands above our quick install script.

Ok I am done, what should I do now?

I recommend that if you’re actually doing to use this application for something other than fun you read the tutorial here:  Installing FreeRadius on CentOS 5/6 or Ubuntu 11 for a more in depth explination about FreeRadius and it’s configuration files.

However if you already know all this or don’t care here are the next steps you should take (and with links on how to do them!)

  1. Secure your MySQL installation!
    We didn’t set a password for root in MySQL during this install, which means anyone can gain access to MySQL using root with no password. MySQL comes with a utility to help us with that called “mysql_secure_installation”, you can execute it by running this in your terminal “/usr/bin/mysql_secure_installation“, or you can read the tutorial on this here: Securing your new MySQL installation with /usr/bin/mysql_secure_installation
  2. Authorize additional servers to use your new FreeRadius server!
    At the moment only applications on the same server as FreeRadius only have access to FreeRadius’s authorization abilities, wouldn’t it be nice to only maintain one configuration of logins across multiple servers and applications? You need to add a few entries to your /etc/raddb/clients.conf (CentOS6) or /etc/freeradius/clients.conf (CentOS5) to do this, or you can read my tutorial on this here: Authorzing External Servers to use your FreeRadius Server
  3. Add additional user accounts to your FreeRadius server!
    If you only needed the one login for your purposes then FreeRadius is severely overkill, so you need to add more user accounts to the MySQL database we created during the script called ‘radius’, within that database is a table called ‘radcheck’ and that’s were you need to add more accounts. If you like however I have an tutorial on how to do this here: Adding and removing users from the FreeRadius Database (MySQL)

Adding and removing users from the FreeRadius Database (MySQL)

In this tutorial I will show you how to add and remove users from the radius database.  It’s a pretty easy task and yes I am even including a script like usual to make it easy for those of you who are not ‘lazy’ just time poor 😉

This is a very popular topic based on visitor statistics! If you need more information or wish to improve upon the content let me know in the comments section.

Okay, before we begin we need:

  • A VPS with FreeRadius / MySQL installed
    If you need to set this up still, take a quick look here for how to set one up in a hurry: Install FreeRadius on CentOS 5 or 6 in just 3 commands!
    Or if you want to learn a little while you set one up then take a look at this How To here:  Installing FreeRadius on CentOS 5/6 or Ubuntu 11
  • The MySQL root password
    Or any account that has the appropriate permissions, to keep it simple though during this tutorial we will use root, you can use whatever account you feel will do the trick though if you like.
  • Some user accounts you want to setup in FreeRadius
    Write down a few usernames and passwords to go with to use during this tutorial and have them ready because we will need them soon.
  • An active putty session already logged into your server, ready to go!
    You can use whatever shell utility you like, but throughout this tutorial we will reference ‘putty’ which is available from here if you would like to download it: http://www.putty.org/
  • About 10-15 minutes of free time to do stuff
    Like I said it’s pretty easy however you might need a little background knowledge of MySQL. However if you managed to install FreeRadius previously you will probably be alright! 🙂

A little about FreeRadius’s MySQL Database

When FreeRadius is used in conjunction with MySQL (most common practice I dare say) it will use a database usually called ‘radius’ and within that database there is a database table called ‘radcheck’. This table is the table we need to interact with as it is the one that contains all the user accounts that can be authenticated with FreeRadius.

It’s important to remember that like a lot of things you can choose what usernames something uses, what the database is called for something and you can even choose to use a remote MySQL server! However for this tutorial we will assume that MySQL and FreeRadius exist on the same server, and that the database is called ‘radius’ and the user account we will use with MySQL is root.

Adding a user account to ‘radcheck’

First connect to your database using the below, if your username is not root, then substitute root in the command for your username.

mysql -uroot -p

Then we need to switch to the radius database, so go ahead and enter in the following at the MySQL prompt:

use radius;

Remember to terminate your MySQL queries with a semi colon!

Now we will run our insert command to add a user. For this example the user we will be adding is Beyonce, and she will have the following login details:
Username: beyonce
Password: putaringonit

The insert code is like the following, I have highlighted the username part we need to replace in red and the password part we need to replace in blue.

INSERT INTO radcheck (id, username, attribute, op, value) VALUES (1,’myusername‘,’User-Password’,’:=’,’mypassword‘);

So here is the code we will run add Beyonce to our FreeRadius server:

INSERT INTO radcheck (id, username, attribute, op, value) VALUES (1,'beyonce','User-Password',':=','putaringonit');

When we run that in the MySQL prompt we should get no errors and Beyonce is now able to log on to our FreeRadius server.

Removing a user account from radcheck

Unfortunately Beyonce has decided to leave our FreeRadius server and so we need to delete her account.

There are a few different ways to target her record in radcheck however we’re going to use her username for this example, but you could also use the id column.

Here is the code to delete a record from radcheck, I have again highlighted the username part we need to change in red.

delete from radcheck where username = ‘myusername

Now, for our example of deleting Beyonce’s login from the database we will do the following:

delete from radcheck where username = 'beyonce'

And we should see from the console output that MySQL has removed her record from radcheck, so she will not be able to pass authentication anymore

Deleting – Afterthoughts…

There are probably times when you want to disable or delete (but keep a record of past user accounts), and if so you will need to think of a solution that is best for you. Generally FreeRadius is used as an endpoint for information, normally there is a greater system in play that sits above FreeRadius that manages user accounts such as WHMCS for example.

It’s also important to remember that deleting someone out of radclient doesn’t kick them out of whatever service they are currently logged into at the time! FreeRadius merely says yes or no at the point of authentication, it doesn’t keep tabs of the user’s session and it doesn’t report back to services to say that someone has been disabled or deleted! So you need to consider how you will manage active sessions with your services for users you want to delete or suspend.

Securing your new MySQL installation with /usr/bin/mysql_secure_installation

After you install MySQL you need to secure it. By default MySQL’s account for ‘root’ does not have a password associated for it, and the server also includes a demo database and all the permissions associated with it. If this server is going to be public or used for anything remotely serious we need to beef up security a bit.

And thats where mysql_secure_installation comes in.

Let’s begin!

After MySQL is installed it will prompt you to run the following command, so that is what we are going to do now!

/usr/bin/mysql_secure_installation

Then you should be greeted by a message asking you to enter the current root password, as there is no current root password we can just hit enter!

Next it will ask us if we want to set a password for root, to this we should say yes!

Now it will ask us for a new password, and then ask us to confirm it, go ahead!

Great now you should see the following success messages and then it should ask us if we want to remove anonymous users, yes we do!

Next it will ask us if we want to allow or disallow root to login remotely, ideally you shouldn’t allow this but there are circumstances where you may want to allow it. In this tutorial we’re going to say we don’t want root to be able to login from anywhere other than localhost, but if your preference is otherwise please google up some information about the subject first! 🙂

Next it will ask us if we want to delete the test database and associated permissions – yes we want to do this!

Lastly it will ask if we want to reload the privilage table, which means our settings will come into immediate effect, to this we will again say yes!

And you’re done! You should see the following message:

This means your server is now post install secure, congrats!

Authorzing External Servers to use your FreeRadius Server

FreeRadius is a fantastic piece of software, and one of the great things about it is practically any piece of software that is either Open Source or allows the development of plugins and extensions will be able to use a FreeRadius installation either by use of an existing plugin or you creating one!

The benefits of a centralized authentication system is very valuable in a network and large scale multi-service provider. A user taking the same credentials with them everywhere they go is a great way to make the user experience of a product or a set of products far more pleasurable and easy – I mean who likes having 1000s of accounts, usernames and passwords?

By default however, FreeRadius only allows (and only has configuration for)localhost to attempt authentication. So how do we add permission for an external server you ask? Let’s find out!

Remote Server Requirements

Before we try to give permission to a server for authentication attempts we need to make sure that a few basic settings of the server suit the requirements of a server for FreeRadius.

A Static IP Address or; A public hostname that will have a valid reverse DNS lookup

Servers with permission to use FreeRadius are identified by a specified IP Address or hostname. For an extra layer of security when it comes to hostnames (because let’s face it, its so easy for a server to pretend that it is someone else with a spoofed hostname) the hostname must pass a reverse DNS lookup when the server attempts to verify an authentication with FreeRadius.

This means that if you want to specify a server by it’s hostname, you need to make sure that it’s reverse dns will pass ok!

A secure connection? or over the public web?

I am a massive fan of running secure connections for your radius auths. Auths are clear-text and that means even if you are collecting a user’s credentials over SSL or other means, when you go to send them to the remote radius server – yep it’s going to be unencrypted and plain to see for every hop on the internet highway between you and your radius server.

So what could you do about this? Well if both your servers are on the local network then there is probably nothing to worry about (except maybe tech savvy IT family members and employees sniffing the network), otherwise probably the best thing you could do is have a VPN connection between your two servers, and configure your servers to talk over that connection. This way traffic between the two servers are encrypted, and as an extra bonus, if the VPN server is setup on the radius server then you could even go as far as reserving an IP address for the VPN user account that is for the external server meaning that your radius couldn’t be more secure as it’s only listening to inbound requests from the VPN DHCP pool!

Anyways, that aside – Let’s begin!

I could talk forever about security practices and suggestive setups and the like, however that’s beyond the scope of this doco, so from here on it we’re going to focus on a very ‘vanilla‘ setup. You can build upon this tutorial however you like and if you have security questions post them in the comments!

To help explain a few ideas we’re going to use the following scenario in our demonstration

The Scenario – Xavier’s Widgets & Co

The company has 2 factories (one in Australia and the other in Taiwan), a head office in Sweden (because that’s a pretty classy place to live) and 2 sales offices (UK and the USA) and an Administration office in Sweden’s HQ building.

The head office has a Samba server that hosts the company’s files, the factories have web based ordering systems (Apache) and the sales offices host nothing of value, they only contribute to the network.

The company requires staff in all locations to be able to login to the Head Office VPN in Sweden, and our factories in Taiwan and Australia using the same credentials for all locations.

So you have come up with this little solution:

free_radius_scenario-AllowingExternalServers

The company wants the most secure setup possible, so your suggesting that they use a VPN server on the radius that gives out the following IP addresses for the following clients:

  • tw.xavwco.com – 192.168.50.101
  • au.xavwco.com – 192.168.50.102

Since the Samba server is on the same LAN as the Radius and the company isn’t concerned about radius traffic over a LAN we can just add a rule for it’s LAN identifier, there is no need to configure it to use the VPN. However the workstation gets it’s IP address from a Windows Server that hosts a DHCP service, so we cannot rely on a static IP in our configuration, what we can use however is the workstation’s hostname which is swadmin1, and reverse dns will work as they are using a local dns server.

They only want the radius to respond to IP addresses that are VPN clients for radius work and localhost. And the great thing is, FreeRadius does this out of the box for you (If an authorization request is received by FreeRadius that is not from an approved source or contains the wrong secret, then the request is ignored and it will appear from the requesting side that nobody is listening!)

Modifying clients.conf

Depending on your linux distro, this file could be in 1 of a couple locations, the most common locations / distros are listed below with a nano command to edit it, you are of course free to use whatever editor your partial to!

CentOS:

nano /etc/raddb/clients.conf

Ubuntu:

nano /etc/freeradius/clients.conf

Once we have this file open we need to scroll right down to the bottom of the file and add our entries for our servers.  First off we will add the Administration PC in the Sweden HQ:

client swadmin1 {
        secret          = 85r9j76to87o8u6ro8
        shortname       = sweedenAdminPc
        nastype         = other
}

And if you save that, then the Admin PC is now able to authenticate logins against FreeRadius

Now we need to add the other servers, notice how the IP address of the server goes in the same spot as where we specified the hostname of the Sweden admin pc:

client 192.168.50.102 {
        secret          = o87qfm9a8m8pasmfjk
        shortname       = auFactory
        nastype         = other
}
client 192.168.50.101 {
        secret          = 2q309dm90jaksuyege
        shortname       = twFactory
        nastype         = other
}

Remember after you make changes you need to restart FreeRadius:

CentOS:

service radiusd restart

Ubuntu:

service freeradius restart

You should see something like this:

service-radiusd-restart-stop-failed-start-ok

And then you’re done! You have now successfully authorized external servers to use your FreeRadius server. Well Done!

Xavier.

 

 

 

Installing FreeRadius on CentOS 5/6 or Ubuntu 11

FreeRadius is the radius solution for Linux in my opinion, and hooks in well with nearly anything you could ever find yourself wanting it to work with! It will work in conjunction with Squid, PPTPD, Apache, WHMCS, and so so many other things.

And the good news is, the installation and configuration is pretty darn simple! In fact it should take you no more than about 15 to 20 minutes to complete by following this guide.

What you will need for this tutorial

  1. A VPS with Centos 5.x or 6.x or Ubuntu 11 (32 or 64 bit is ok)
  2. About 20 minutes of free time
  3. Putty terminal already connected to your server, ready to go!

Need a VPS? I highly recommend DigitalOcean if you are shopping around, pretty quick support and their entire website is perfectly automated. It’s a very impressive place to hang out!

Let’s begin, Installing the packages

First we need to install the freeradius package and it’s dependencies:

CentOS 5:

yum install freeradius2 freeradius2-mysql freeradius2-utils mysql-server -y

CentOS 6:

yum install freeradius freeradius-mysql freeradius-utils mysql-server -y

Ubuntu:

apt-get install freeradius freeradius-mysql freeradius-utils mysql-server

This should go off without any problems at all, and let’s continue on.

The next thing we should do is setup our MySQL installation.

Installing MySQL

CentOS:

service mysqld start

Ubuntu:

service mysql start

IMPORTANT! Currently the MySQL database is pretty unprotected, make sure you run the mysql_secure_installation at the end of this step!

Now we will create the database needed for Free Radius to use and also populate with with tables and apply the required permissions for free radius to connect to it. You can if you wish change the username and password from the below (I would probably change the password even though we’re only adding authentication from localhost) however please write down your changes next to you as you will need them later!

CentOS:

mysql -uroot <<EOFMYSQL
CREATE DATABASE radius;
GRANT ALL PRIVILEGES ON radius.* TO radius@localhost IDENTIFIED BY "radpass";
flush privileges;
use radius;
SOURCE /etc/raddb/sql/mysql/schema.sql
exit
EOFMYSQL

Ubuntu:

mysql -uroot <<EOFMYSQL
CREATE DATABASE radius;
GRANT ALL PRIVILEGES ON radius.* TO radius@localhost IDENTIFIED BY "radpass";
flush privileges;
use radius;
SOURCE /etc/freeradius/sql/mysql/schema.sql
exit
EOFMYSQL

Okay, now it’s time to secure our MySQL installation by typing:

/usr/bin/mysql_secure_installation

This will start the MySQL secure install application, it will ask you various questions about the install environment you would like to keep, and ask you to change the root password. Generally speaking apart from changing the root password your answer to everything else should be the default one (yes). There are circumstances to choose other options but that is outside the scope of this tutorial sorry. Plenty of reading on Google for those of you who are interested!

I cannot stress how important this step is however, please make sure you complete it before continuing!

Optional – Installing nano

Okay, now it’s config editing time, for the examples we will use the editor ‘nano’ as it’s my favorite for quick and dirty but basic tasks. You’re free however to use whatever you are comfortable with.

First we need to make sure nano is installed (you can skip this if you’re going to use something other than nano)

CentOS:

yum install nano -y

Ubuntu:

apt-get install nano -y

Edit sql.conf

CentOS:

nano /etc/raddb/sql.conf

Ubuntu:

nano /etc/freeradius/sql.conf

You need to make sure that the values for the following are the same in your file. If you changed any of the details in the MySQL earlier (such as the radius username or password) make sure it’s reflected here too.

        # Connection info:
	server = "localhost"
	#port = 3306
	login = "radius"
	password = "radpass"

	# Database table configuration for everything except Oracle
	radius_db = "radius"

Edit radiusd.conf

CentOS:

nano /etc/raddb/radiusd.conf

Ubuntu:

nano /etc/freeradius/radiusd.conf

We need to make sure that a line is uncommented (no hash symbol on the same line of text before it)
Do a search in nano (using Ctrl+W) and type in “sql.conf” (without quotes) and make sure that the line matching that below is uncommented.

$INCLUDE  sql.conf

Edit sites-available/default

CentOS:

nano /etc/raddb/sites-available/default

Ubuntu:

nano /etc/freeradius/sites-available/default

There are two occurrences of “sql” (no quotes) within this file that need to be uncommented. One is inside the section “authorize” and the other inside the section “accounting”.

Edit sites-available/inner-tunnel

CentOS:

nano /etc/raddb/sites-available/inner-tunnel

Ubuntu:

nano /etc/freeradius/sites-available/inner-tunnel

There are two occurrences of “sql” (no quotes) within this file that need to be uncommented. One is inside the section “authorize” and the other inside the section “session”.

Edit clients.conf

CentOS:

nano /etc/raddb/clients.conf

Ubuntu:

nano /etc/freeradius/clients.conf

Inside this file there is a setting called “secret” (no quotes) that we need to change from the default value of “testing123” (no quotes) as that’s a bit too obvious. It probably looks like the below by default in your file:

secret = testing123

Let’s quickly visit random.org and grab something a bit more secure, you don’t have to – you can set it to your pet’s name if you wish! However  I am a fan of secure passwords, and random stuff. if you are too, click this link (opens in a new window and different every time) and pick a random one one to use.

Now it should look something like this:

secret = mL9fXjMfQ5rjQ6fB

Did we break it? Checking to see if Radius works ok

Now is the hmmm part, did we follow the tutorial correctly and will FreeRadius start ok? let’s find out!

CentOS:

service radiusd restart

Ubuntu:

service freeradius restart

You should see something like this:

service-radiusd-restart-stop-failed-start-ok

Don’t worry if the stopping radius says it didn’t finish ok, that’s because it wasn’t already running! What is important is if it says it started ok or not, if it didn’t then go back over the config files and make sure they are correct. If it fails to start it should also give you a clue why to help you figure out what went wrong.

Okay, we’re good. Let’s stop the radius server and continue on

You can stop free radius by entering the appropriate command below:

CentOS:

service radiusd stop

Ubuntu:

service freeradius stop

service_radiusd_stop

Optional – Authorizing other servers to access this Radius Server – clients.conf

Sometimes you will only want a radius server to authenticate users through services and applications that are on the same server as the radius server, so if that’s the case then you only need the secret you set in the final config file we edited previously. However it makes sense if you have many services and applications on different servers that you want people to have the same username and password for to use the 1 radius server for all of them. So we need to give authority to these servers to be able to come knock on our new radius server’s door and ask “Is this username and password for John Smith valid?”

And this is were we specify the ip address / hostname and the password for those other servers to use so they can verify logins against your radius server!

Open up clients.conf by using the appropriate command:

CentOS:

nano /etc/raddb/clients.conf

Ubuntu:

nano /etc/freeradius/clients.conf

Yep this is the same file we were in before changing the secret for requests to the radius server that come from localhost. This time we need to scroll right down to the bottom of the config file (in nano you can hold Ctrl+V to have a “pgdn” effect and mover there quicker) and paste in your version of the below:

client APP_SERVER_IP {
	secret		= A PASSWORD FOR THE APP SERVER
	shortname	= A NAME FOR THE APP SERVER
        nastype         = other
}

Here is a quick explanation of the properties we need to set:

APP_SERVER_IP - this is the ip address or the public hostname (domain name) of the server accessing our radius server

secret - this is the password that should be expected from the application server

shortname - this is a nickname for the application server that will be accessing our new radius server

nastype - just leave this as other

You can add as many of these as you need, but lets only add the one for now for testing purposes (keep it simple) and you can always come back later when you have proven everything else is working!

Making changes to the radius config files

When you do make a change to any of the radius config files, the changes are not automatically loaded, you need to restart the radius service for it to pick up it’s configuration again.

To do this, run the appropriate command from those given below:

CentOS:

service radiusd restart

Ubuntu:

service freeradius restart

Adding a user to the Radius database for authentication

Okay we are nearly there I promise! Next we have to add users to the radius database to be used later for authentication. To do this we need to open MySQL again but this time we will include the -p parameter indicating that the user root is password protected and we have to supply MySQL with one!

mysql -uroot -p

MySQL will now ask you for your password, type it in followed by enter.

Now we switch to the radius database:

use radius;

Then we run some SQL to add the user to the database. The example below will add a user called ‘myusername’ with a password of ‘mypassword’, don’t copy this as it’s not very secure is it being posted all over the internet, change them to something of your own first! 🙂

INSERT INTO `radcheck` (`id`, `username`, `attribute`, `op`, `value`) VALUES (1,'myusername','User-Password',':=','mypassword');

Then we type exit to close MySQL and return normal bash prompt.

exit

Testing out our Radius server

Ok you remember earlier when I told you to change the secret for localhost and write it down next to you? You’re going to need it now.

First lets give radius one last restart to make sure it’s running ok and the latest config is loaded.

CentOS:

service radiusd restart

Ubuntu:

service freeradius restart

Now we’re going to try out that user we created in the radius database by typing this into the shell:

radtest myusername mypassword 127.0.0.1 0 radpass

To help you with what is going on here, here is an explanation of the command’s parameters:

myusername - this is the username for the user we created through MySQL in the radius database in the previous step.

mypassword - this is the password for the user we created through MySQL in the radius database in the previous step.

127.0.0.1 - this is the ip address of the radius server, leave that as localhost for now.

0 - this is important but we wont go into it in this tutorial, for now its a magical required zero.

radpass - this is the secret we changed earlier that i told you to write down next to you.

When you submit your command you should see “rad_recv: Access-Accept” which means well done your radius is working.

radtest-accept-packet

Some common reasons for it not working:

  • If you see it try 3 times and then fail, this could mean 1 of two things:
    • Your radius service isn’t running!
    • The password (secret for an application attempting to authenticate on your radius, not the user’s pasword) is incorrect. – this is because when the password is wrong, FreeRadius acts like there is no one listening, this helps protect you against would be hackers!
  • If you see it try once and it reports that it is invalid then it could mean:
    radtest-reject-packet
     

    • The user’s password is incorrect
    • MySQL service is not running! – Radius will startup ok even if MySQL didn’t!
  • If you see the message: “Access-Reject packet from host 127.0.0.1” it means:
    • The user’s username and or password is incorrect.

Hopefully these hints helped you out of your problem, but if not, this final step might help you.

Radius debug mode

Okay for this you will need two putty sessions open, so go ahead and open another.

First we need to make sure that FreeRadius is stopped, so in the first putty session type the applicable command of the following:

CentOS:

service radiusd stop

Ubuntu:

service freeradius stop

Then in the same window type in the following to start the FreeRadius debug console:

radiusd -X

First you will see a bunch of text scrolling, that’s the radius setting itself up, look for warnings or errors here, they could be signs of a broken config file.

Once it settles it’s ready for another attempt, so in your window have another go at testing your login against the radius server and watching for the reaction of radiusd in the other window.
radiusd-x-ready

If you see: “Received packet from x.x.x.x with invalid Message-Authenticator!” This means that the secret (not the user’s password but the radius secret) is incorrect. When this happens FreeRadius will just pretend it’s not there, so you may see your client also attempting to connect more than once (usually 3 times) before stopping.
radiusd-reject-packet

Most errors are pretty self explanatory, but if you have any problems, feel free to leave a comment!

Thanks,

Xavier.

 

How to install a PPTPD VPN server on Centos 6.X in just 4 commands

First off, a big special thanks goes out to “Drew Moris” for the script we will use today. You can view the original post on his website for this script here: http://drewsymo.com/2013/11/how-to-install-pptp-vpn-server-on-centos-6-x/

Today we’re going to install a PPTPD VPN Server in just a few commands – Setting up a PPTPD server can be a little fiddly and can sometimes be tricky, however thanks to a bit of ingenuity of Drew’s, we can knock over a fully working installation of PPTPD in just a few moves, let’s get started!

What you will need to do this tutorial:

  1. A VPS or Dedicated server that is running CentOS 6.x, don’t worry this script is architecture independent, x86 or 64 will be fine.
  2. About 5 minutes of time and an already primed session of Putty ready to go
  3. OpenVZ users only: There is always that one special kid in the class isn’t there? You will need to do 2 more things which are:
    1. Please make sure you enable both TUN/TAP and PPP in your VPN Control Panel
    2. There is an extra IPTables rule you will need to add that is at the end of this tutorial, please make sure you do!

Need a VPS? I highly recommend DigitalOcean if you are shopping around, pretty quick support and their entire website is perfectly automated. It’s a very impressive place to hang out!

Okay, let’s begin!

In your ready to go putty session run the following commands:

yum install -y git
cd /opt && git clone git://github.com/drewsymo/VPN.git
cd VPN && bash vpn-setup-vanilla.sh

OpenVZ Users (One last thing)

You need to also run an additional command for IPTables so your data is routed correctly:

iptables -t nat -A POSTROUTING -j SNAT --to-source x.x.x.x

Just replace the x.x.x.x with the IP address of your venet0 IP.

Final Thoughts

The best test to perform after a script job is to make sure that if the server reboots that everything comes back online automatically and without you having to do anything to help it.

As great as this script from Drew is, a security concern is that you’re blindly installing a script from the internet that may have been altered maliciously since Drew made it or I wrote about it (without anyone knowing of course). So I wouldn’t recommend this as a script to use in a serious application, unless you download it yourself first and eyeball it from beginning to end. However if you’re just doing this for fun or research and you’re not a hacker, filthy rich or Julian Assange then you should be pretty fine using it however you wish! 🙂

Enjoy!

Xavier.

Could not determine this machines public hostname. Please configure one or set 'visible_hostname'. - Squid

Could not determine this machines public hostname. Please configure one or set ‘visible_hostname’. – Squid

During the startup sequence of Squid you may encounter the following Warning:

Stopping squid: 2013/12/13 03:42:05| WARNING: Could not determine this machines public hostname. Please configure one or set ‘visible_hostname’.

This is caused because squid is unable to work out what your hostname is, it will attempt to do a reverse IP lookup on it too, so if your DNS changes have not fully had a chance to propogate yet, this could also be the cause of the warning.

The simplest solution is to manually set the hostname in the squid.conf file and then squid will have no reason to work it out for itself.

To do this open your squid.conf file:

nano /etc/squid/squid.conf

and add or update this line to your configuration file:

visible_hostname [your hostname for squid]

Where you see [your hostname for squid] you should replace it with the hostname of your machine (for example: mysquidserver.com)

When you have done this, save your changes and then execute the following command to restart squid:

service squid restart

In a few moments you should see that squid has come back online again, and there should be no more warning message about the hostname.