How to implement QOS with L7 (layer7) support

Linux QoS built with tc and HTB.

Requirements

– iproute2
– act_mirred and act_connmark kernel support
– lradaelli85 QoS scripts (https://github.com/lradaelli85/tc-QOS)
– (optional) nDPI for L7 classification

Features

– Handle Download traffic (i.e traffic coming from WAN)
– Handle Upload traffic (i.e traffic to WAN)
– (optional) Classify L7 traffic
– (optional) Slowdown (set a low priority) those connections that go beyond a fixed amount of traffic (i.e big download)

Introduction

The aim of this script is to guarantee (bandwidth can’t go below this value) , limit (maximum bandwidth usable) and prioritize certain kind of traffic.

It has been designed to share the same internet link between different sources.

This is done by using classes.

download/upload/guaranteed/limit/applications values present in qos.cfg have been used only as reference

This script has been designed to use three different kind of classes:

– Bulk traffic

This class has a low guaranteed bandwidth,medium priority and it can use all the available up/down bandwidth
All low-ports (0-1023, except some) are classified as bulk traffic.
Modify the QoS.sh file if this is not what you want

– Low priority traffic

Traffic that has to be limited (small amount of available bandwidth) with a low priority.
All high-ports (1024-65535, except some) are classified as low priority traffic.
YOUTUBE,TWITTER,FACEBOOK,DROPBOX,SPOTIFY applications if L7 is enabled.
Modify the QoS.sh and qos.cfg files if this is not what you want

– High priority traffic

Traffic that has to be prioritized.
This class has an high guaranteed bandwidth, high priority and it can use all the available up/down bandwidth
HTTP(s),SSH,DNS,VOIP,IPsec,OpenVPN are classified as high priority traffic.
STUN,RTP,H323,HANGOUT,SKYPE,OFFICE 365 applications if L7 is enabled
Modify the QoS.sh and qos.cfg files if this is not what you want

When a class requests less than the amount assigned, the remaining (excess) bandwidth is distributed to other classes which request service.

Classes with higher priority are offered excess bandwidth first. But rules about guaranteed rate (can’t go below this value ) and ceil (maximum bandwidth usable by a class) are still met.

This script automatically enable forwarding and source NAT

To learn more about HTB take a look to the below links (thanks to the Author)

http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm

http://luxik.cdi.cz/~devik/qos/htb/manual/theory.htm

Configuration and usage

Edit the qos.cfg file and set the variables accordingly.

For each variable there is a short explanation

– disable the slowdown feature set the `ENABLE_SLOWDOWN` value to `off`
– In order to disable the L7 classification set the `ENABLE_L7` value to `off`

To check supported applications run `iptables -m ndpi –help`

Usually the `iptables mark` parameters does not need to be changed,do it only if you know what are you doing

**NO FILTER POLICY HAVE BEEN ADDED**

The qos_class_mapping.cfg file contains a mapping (human readable) between the class ID and the class Description.
If you will change the `iptables mark` values in the qos.cfg remember to update the qos_class_mapping.cfg accordingly.

To run the script issue the below command

./QoS.sh start

If you want to have some statistics about traffic QoS classes run

./QoS.sh stats

Below an example of the output

## Download QoS classes ##
+---(1:1) htb rate 1Gbit ceil 1Gbit burst 15125b cburst 1375b
| Sent 1582 bytes 10 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(High-Priority-Download#1:11) htb prio 0 rate 1Mbit ceil 4Mbit burst 15Kb cburst 1600b
| Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(Low-Priority-Download#1:10) htb prio 7 rate 512Kbit ceil 512Kbit burst 15Kb cburst 1600b
| Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(Bulk-Download-Traffic#1:12) htb prio 5 rate 256Kbit ceil 1Mbit burst 15Kb cburst 1600b
Sent 1582 bytes 10 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0

## Upload QoS classes ##
+---(1:1) htb rate 1Gbit ceil 1Gbit burst 15125b cburst 1375b
| Sent 1249 bytes 16 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(Bulk-Upload-traffic#1:22) htb prio 5 rate 64Kbit ceil 2Mbit burst 15Kb cburst 1600b
| Sent 1249 bytes 16 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(Low-Priority-Upload#1:20) htb prio 7 rate 512Kbit ceil 1Mbit burst 15Kb cburst 1600b
| Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
| rate 0bit 0pps backlog 0b 0p requeues 0
|
+---(High-Priority-Upload#1:21) htb prio 0 rate 512Kbit ceil 2Mbit burst 15Kb cburst 1600b
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0

I decided to classify as bulk traffic all low ports traffic (0-1023) explicitly (except some tcp/udp ports.See Introduction).
Actually,you can also classify as bulk all the not-classified traffic (i.e no high/low prio traffic) uncommenting
the `#default $DOWN_BULK_MARK` line in QoS.sh file.

Notes

if you uncomment the `#default $DOWN_BULK_MARK` in QoS.sh,the locally-generated-traffic will be classified as bulk by default ,since this script classify only traffic that will be routed to WAN interface.

Credits

Credits to lradaelli85  for the scripts and explaination

How to install PHP 7.2 on Ubuntu 14.04 (ISPConfig 3.1)

Ubuntu 14.04 is shipped with PHP 5.5.9 as default PHP version. Since most of CMS now want a most recent version of PHP we gonna explain how-to install a most recent version of PHP.

I’ll explain how to compile and then use PHP 7.2.6 on Ubuntu 14.04 LTS with ISPConfig.

We will see also how-to configure ISPConfig for using the new PHP engine.

Let’s start by creating the necessary folders, downloading the latest PHP 7.2 version from php.net website and extract it:

mkdir -p /opt/php-7.2
mkdir /usr/local/src/php7-build
cd /usr/local/src/php7-build
wget http://de2.php.net/get/php-7.2.6.tar.bz2/from/this/mirror -O php-7.2.6.tar.bz2
tar jxf php-7.2.6.tar.bz2

cd php-7.2.6

Before starting we need to Install the necessary libraries and building tools for compile our PHP version.
If you are not logged-in as root, run the commands with sudo in front of each commands:

apt-get install build-essential nano

apt-get install libfcgi-dev libfcgi0ldbl libjpeg-turbo8-dbg libmcrypt-dev libssl-dev libc-client2007e \
libc-client2007e-dev libxml2-dev libbz2-dev libcurl4-openssl-dev libjpeg-dev libpng12-dev libfreetype6-dev \
libkrb5-dev libpq-dev libxml2-dev libxslt1-dev

ln -s /usr/lib/libc-client.a /usr/lib/x86_64-linux-gnu/libc-client.a

After the installation of the required build-tools, we can now go ahead and start configuring & enabling the PHP modules that we want to use, before compiling PHP:

./configure --prefix=/opt/php-7.2 --with-pdo-pgsql --with-zlib-dir --with-freetype-dir --enable-mbstring --with-libxml-dir=/usr --enable-soap --enable-calendar --with-curl --with-mcrypt --with-zlib --with-gd --with-pgsql --disable-rpath --enable-inline-optimization --with-bz2 --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --enable-exif --enable-bcmath --with-mhash --enable-zip --with-pcre-regex --with-pdo-mysql --with-mysqli --with-mysql-sock=/var/run/mysqld/mysqld.sock --with-jpeg-dir=/usr --with-png-dir=/usr --enable-gd-native-ttf --with-openssl --with-fpm-user=www-data --with-fpm-group=www-data --with-libdir=/lib/x86_64-linux-gnu --enable-ftp --with-imap --with-imap-ssl --with-kerberos --with-gettext --with-xmlrpc --with-xsl --enable-opcache --enable-fpm

Now we can start compiling PHP and install the new compiled module, our new version of PHP will be installed under /opt/php-7.2/ in order to do not interfere with other system stuff, on SSH now type:

make
make install

The compile will take a while (it vary from the server hardware). Once the compile end without errors we can proceed with the next steps

Copy php.ini, php-fpm.conf and www.conf configuration files under /opt/php-7.2/

cp /usr/local/src/php7-build/php-7.2.6/php.ini-production /opt/php-7.2/lib/php.ini
cp /opt/php-7.2/etc/php-fpm.conf.default /opt/php-7.2/etc/php-fpm.conf
cp /opt/php-7.2/etc/php-fpm.d/www.conf.default /opt/php-7.2/etc/php-fpm.d/www.conf

After copying the files we now proceed by adjust the php-fpm.conf file.

I have used the editor vim but you can use you preferred editor like for ex. nano

vim /opt/php-7.2/etc/php-fpm.conf

Inside the configuration file comment out the pid section, I have changed the pid filename in order to have the possibility of compile and use multiple PHP version at the same time, if you leave it as default and then compile other version of PHP and use the same pid filename, you will incure in some issues. After edit the file, save it and proceed with the next step.

[...]
pid = run/php-7.2-fpm.pid
[...]

We need now to change also www.conf file in order to have php-fpm listening on different port (on the default port 9000 and on port 8999 I have already another php-fpm version running). I have chosen the port 8998

vim /opt/php-7.2/etc/php-fpm.d/www.conf
[...]
listen = 127.0.0.1:8998
[...]

We are almost done now, there are only few steps to be done, first of all the init.d file, otherwise our php-fpm will never start automatically. Let’s create now the init.d file:

vim /etc/init.d/php-7.2-fpm
#! /bin/sh
### BEGIN INIT INFO
# Provides:          php-7.2-fpm
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts php-7.2-fpm
# Description:       starts the PHP FastCGI Process Manager daemon
### END INIT INFO
php_fpm_BIN=/opt/php-7.2/sbin/php-fpm
php_fpm_CONF=/opt/php-7.2/etc/php-fpm.conf
php_fpm_PID=/opt/php-7.2/var/run/php-7.2-fpm.pid
php_opts="--fpm-config $php_fpm_CONF"
wait_for_pid () {
        try=0
        while test $try -lt 35 ; do
                case "$1" in
                        'created')
                        if [ -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                        'removed')
                        if [ ! -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                esac
                echo -n .
                try=`expr $try + 1`
                sleep 1
        done
}
case "$1" in
        start)
                echo -n "Starting php-fpm "
                $php_fpm_BIN $php_opts
                if [ "$?" != 0 ] ; then
                        echo " failed"
                        exit 1
                fi
                wait_for_pid created $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        stop)
                echo -n "Gracefully shutting down php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -QUIT `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed. Use force-exit"
                        exit 1
                else
                        echo " done"
                       echo " done"
                fi
        ;;
        force-quit)
                echo -n "Terminating php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -TERM `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        restart)
                $0 stop
                $0 start
        ;;
        reload)
                echo -n "Reload service php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -USR2 `cat $php_fpm_PID`
                echo " done"
        ;;
        *)
                echo "Usage: $0 {start|stop|force-quit|restart|reload}"
                exit 1
        ;;
esac

Change the permission and set the default run levels

chmod 755 /etc/init.d/php-7.2-fpm
update-rc.d php-7.2-fpm defaults

I strongly suggest to enable the Zend OPcache. In order to do it, edit the php.ini file which is located under /opt/php-7.2/lib/php.ini

vim /opt/php-7.2/lib/php.ini
zend_extension=opcache.so

Let’s tell now to ISPConfig where to find the new PHP engine.

Log-In in ISPConfig 3 panel and configure the new PHP version under System > Additional PHP Versions > Add new PHP version.

On the Name tab, you just fill in a name for the PHP version (e.g. PHP 7.2.6) . This is name is then displayed on the website settings in ISPConfig:

Go to the FastCGI Settings tab and fill out the fields as follows:

PHP FastCGI binary: /opt/php-7.2/bin/php-cgi
php.ini directory: /opt/php-7.2/lib

Then go to the PHP-FPM Settings tab and fill out the fields as follows:

PHP-FPM init script: /etc/init.d/php-7.2-fpm
php.ini directory: /opt/php-7.2/lib
PHP-FPM pool directory: /opt/php-7.2/etc/php-fpm.d

Enjoy your new PHP!

How to install PHP 7.0 on Ubuntu 14.04 (ISPConfig 3.1)

Ubuntu 14.04 is shipped with PHP 5.5.9 as default PHP version. Since most of CMS now want a most recent version of PHP we gonna explain how-to install a most recent version of PHP.

I’ll explain how to compile and then use PHP 7.0.30 on Ubuntu 14.04 LTS with ISPConfig.

We will see also how-to configure ISPConfig for using the new PHP engine.

Let’s start by creating the necessary folders, downloading the latest PHP 7.0 version from php.net website and extract it:

mkdir -p /opt/php-7.0
mkdir /usr/local/src/php7-build
cd /usr/local/src/php7-build
wget http://de2.php.net/get/php-7.0.30.tar.bz2/from/this/mirror -O php-7.0.30.tar.bz2
tar jxf php-7.0.30.tar.bz2

cd php-7.0.30

Before starting we need to Install the necessary libraries and building tools for compile our PHP version.
If you are not logged-in as root, run the commands with sudo in front of each commands:

apt-get install build-essential nano

apt-get install libfcgi-dev libfcgi0ldbl libjpeg-turbo8-dbg libmcrypt-dev libssl-dev libc-client2007e \
libc-client2007e-dev libxml2-dev libbz2-dev libcurl4-openssl-dev libjpeg-dev libpng12-dev libfreetype6-dev \
libkrb5-dev libpq-dev libxml2-dev libxslt1-dev

ln -s /usr/lib/libc-client.a /usr/lib/x86_64-linux-gnu/libc-client.a

After the installation of the required build-tools, we can now go ahead and start configuring & enabling the PHP modules that we want to use, before compiling PHP:

./configure --prefix=/opt/php-7.0 --with-pdo-pgsql --with-zlib-dir --with-freetype-dir --enable-mbstring --with-libxml-dir=/usr --enable-soap --enable-calendar --with-curl --with-mcrypt --with-zlib --with-gd --with-pgsql --disable-rpath --enable-inline-optimization --with-bz2 --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --enable-exif --enable-bcmath --with-mhash --enable-zip --with-pcre-regex --with-pdo-mysql --with-mysqli --with-mysql-sock=/var/run/mysqld/mysqld.sock --with-jpeg-dir=/usr --with-png-dir=/usr --enable-gd-native-ttf --with-openssl --with-fpm-user=www-data --with-fpm-group=www-data --with-libdir=/lib/x86_64-linux-gnu --enable-ftp --with-imap --with-imap-ssl --with-kerberos --with-gettext --with-xmlrpc --with-xsl --enable-opcache --enable-fpm

Now we can start compiling PHP and install the new compiled module, our new version of PHP will be installed under /opt/php-7.0/ in order to do not interfere with other system stuff, on SSH now type:

make
make install

The compile will take a while (it vary from the server hardware). Once the compile end without errors we can proceed with the next steps

Copy php.ini, php-fpm.conf and www.conf configuration files under /opt/php-7.0/

cp /usr/local/src/php7-build/php-7.0.25/php.ini-production /opt/php-7.0/lib/php.ini
cp /opt/php-7.0/etc/php-fpm.conf.default /opt/php-7.0/etc/php-fpm.conf
cp /opt/php-7.0/etc/php-fpm.d/www.conf.default /opt/php-7.0/etc/php-fpm.d/www.conf

After copying the files we now proceed by adjust the php-fpm.conf file.

I have used the editor vim but you can use you preferred editor like for ex. nano

vim /opt/php-7.0/etc/php-fpm.conf

Inside the configuration file comment out the pid section, I have changed the pid filename in order to have the possibility of compile and use multiple PHP version at the same time, if you leave it as default and then compile other version of PHP and use the same pid filename, you will incure in some issues. After edit the file, save it and proceed with the next step.

[...]
pid = run/php-7.0-fpm.pid
[...]

We need now to change also www.conf file in order to have php-fpm listening on different port (on the default port 9000 and on port 8999 I have already another php-fpm version running). I have chosen the port 8998

vim /opt/php-7.0/etc/php-fpm.d/www.conf
[...]
listen = 127.0.0.1:8998
[...]

We are almost done now, there are only few steps to be done, first of all the init.d file, otherwise our php-fpm will never start automatically. Let’s create now the init.d file:

vim /etc/init.d/php-7.0-fpm
#! /bin/sh
### BEGIN INIT INFO
# Provides:          php-7.0-fpm
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts php-7.0-fpm
# Description:       starts the PHP FastCGI Process Manager daemon
### END INIT INFO
php_fpm_BIN=/opt/php-7.0/sbin/php-fpm
php_fpm_CONF=/opt/php-7.0/etc/php-fpm.conf
php_fpm_PID=/opt/php-7.0/var/run/php-7.0-fpm.pid
php_opts="--fpm-config $php_fpm_CONF"
wait_for_pid () {
        try=0
        while test $try -lt 35 ; do
                case "$1" in
                        'created')
                        if [ -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                        'removed')
                        if [ ! -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                esac
                echo -n .
                try=`expr $try + 1`
                sleep 1
        done
}
case "$1" in
        start)
                echo -n "Starting php-fpm "
                $php_fpm_BIN $php_opts
                if [ "$?" != 0 ] ; then
                        echo " failed"
                        exit 1
                fi
                wait_for_pid created $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        stop)
                echo -n "Gracefully shutting down php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -QUIT `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed. Use force-exit"
                        exit 1
                else
                        echo " done"
                       echo " done"
                fi
        ;;
        force-quit)
                echo -n "Terminating php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -TERM `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        restart)
                $0 stop
                $0 start
        ;;
        reload)
                echo -n "Reload service php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -USR2 `cat $php_fpm_PID`
                echo " done"
        ;;
        *)
                echo "Usage: $0 {start|stop|force-quit|restart|reload}"
                exit 1
        ;;
esac

Change the permission and set the default run levels

chmod 755 /etc/init.d/php-7.0-fpm
update-rc.d php-7.0-fpm defaults

I strongly suggest to enable the Zend OPcache. In order to do it, edit the php.ini file which is located under /opt/php-7.0/lib/php.ini

vim /opt/php-7.0/lib/php.ini
zend_extension=opcache.so

Let’s tell now to ISPConfig where to find the new PHP engine.

Log-In in ISPConfig 3 panel and configure the new PHP version under System > Additional PHP Versions > Add new PHP version.

On the Name tab, you just fill in a name for the PHP version (e.g. PHP 7.0.30) . This is name is then displayed on the website settings in ISPConfig:

Go to the FastCGI Settings tab and fill out the fields as follows:

PHP FastCGI binary: /opt/php-7.0/bin/php-cgi
php.ini directory: /opt/php-7.0/lib

Then go to the PHP-FPM Settings tab and fill out the fields as follows:

PHP-FPM init script: /etc/init.d/php-7.0-fpm
php.ini directory: /opt/php-7.0/lib
PHP-FPM pool directory: /opt/php-7.0/etc/php-fpm.d

Enjoy your new PHP!

How-to make a Raspberry Pi 3 as a 3G/4G router

20161107_231344 

In this article we will explain how to configure and use our Raspberry Pi 3 to act as a 3G/4G Wi-Fi Router

Installing the required packages

First of all we need to install the DHCP Server, hostapd (for create a Wi-Fi AP) and usb-modeswitch (for the 3G/4G modem).

sudo apt-get install usb-modeswitch usb-modeswitch-data hostapd isc-dhcp-server

 


 

Configure DHCP Server

We proceed now to configure the DHCP Server in order to release IPs to our clients through Wi-Fi (wlan0).
Let’s start by configuring the DHCP subnet, IP range and DNS Server to push to the clients

/etc/dhcp/dhcpd.conf

#
# Configuration file for ISC dhcpd for Debian
#
#

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# Internal subnet.
subnet 10.5.5.0 netmask 255.255.255.0 {
range 10.5.5.26 10.5.5.50;
option domain-name-servers 8.8.8.8, 8.8.4.4;
option domain-name "local-network";
option routers 10.5.5.1;
option broadcast-address 10.5.5.255;
default-lease-time 600;
max-lease-time 7200;
}

After configuring the DHCP subnet we should specify on which interface/interfaces the DHCP Server should listen, for doing this we edit the following file and insert the interface in the “INTERFACES” section:

/etc/default/isc-dhcp-server

# Defaults for isc-dhcp-server initscript
# sourced by /etc/init.d/isc-dhcp-server
# installed at /etc/default/isc-dhcp-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPD_CONF=/etc/dhcp/dhcpd.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPD_PID=/var/run/dhcpd.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="wlan0"

 


 

Configure Wi-Fi AP

We configure now hostapd in order to setup a Wi-Fi network for the clients like Smartphone, Laptop, Tablets, etc..
If doesn’t already exist create a file under “/etc/hostapd/hostapd.conf”

touch /etc/hostapd/hostapd.conf

Then inside the file put the following configuration and change the field ssid and wpa_passphrase with a Wi-Fi name to show to your devices and the password for access to the Wi-Fi

### Wireless network interface ###
interface=wlan0

### Driver ###
driver=nl80211

### Network name SSID ###

ssid=

your-ssid-here

### Set frequency to 2.4 Ghz ###
hw_mode=g

### Channel number ###
channel=4

### Enable Wi-Fi N ###
ieee80211n=1

### Enable WMM ###
wmm_enabled=1

### Enable 40 Mhz channels ###
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]

### Allow all MAC Address ###
macaddr_acl=0

### Use WPA Auth ###
auth_algs=1

### Require clients to know the network name ###
ignore_broadcast_ssid=0

### Use WPA2 ###
wpa=2

### Enable Pre-Shared Key ###
wpa_key_mgmt=WPA-PSK

### Network key ###
wpa_passphrase=

password-here

### Use AES ###
rsn_pairwise=CCMP

Now we should tell to the which configuration file the init script should use, in order to do this we need to edit the file “/etc/default/hostapd” and comment out the parameter “DAEMON_CONF=” and fill it with the path to the previously created hostapd configuration file. At the end the file should be like that:

# Defaults for hostapd initscript
#
# See /usr/share/doc/hostapd/README.Debian for information about alternative
# methods of managing hostapd.
#
# Uncomment and set DAEMON_CONF to the absolute path of a hostapd configuration
# file and hostapd will be started during system boot. An example configuration
# file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz
#
DAEMON_CONF="/etc/hostapd/hostapd.conf"

# Additional daemon options to be appended to hostapd command:-
#       -d   show more debug messages (-dd for even more)
#       -K   include key data in debug messages
#       -t   include timestamps in some debug messages
#
# Note that -B (daemon mode) and -P (pidfile) options are automatically
# configured by the init.d script and must not be added to DAEMON_OPTS.
#
#DAEMON_OPTS=""

 


 

Configure the network interface and Firewall (iptables) rules

We configure now the interface wlan0 in the file “/etc/network/interfaces” in order to disable the automatic configuration through wpa_supplicant and assign a static IP to the wlan0 interface and make it as a default gateway for the clients.
Comment the section “iface wlan0 inet manual” and “wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf”.

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

iface eth0 inet manual

allow-hotplug wlan0
#iface wlan0 inet manual
#    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

iface wlan0 inet static
        address 10.5.5.1
        netmask 255.255.255.0
        network 10.5.5.0
        broadcast 10.5.5.255

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

We need now to setup our Raspberry Pi as a “Router” so we should now enable the packets forwarding into the kernel with:

sudo echo 1 > /proc/sys/net/ipv4/ip_forward

But this will only enable temporary the packet forwarding so in order to make it permanent we should edit the file “/etc/sysctl.conf” and add (or comment out if exist)

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

The configuration is almost finished, we need only to setup the iptables rules

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

Save the current iptables rule with

iptables-save > /etc/iptables.ipv4.nat

We configure the rule to be loaded at boot by edit the file “/etc/rc.local” and add at the end of the file (before the “exit 0) the following lines:

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

Why “usb0” interface in the iptables rules?
Probably you are asking why I’ve chosen the usb0 interface in the iptables rules instead of ppp0. I’ve chosen usb0 because my 3G key (a ZTE MF730) is switched by the usb-modeswitch project as an USB Ethernet interface (this happens also for some Huawei 3G/4G key).


 

Starting the services

The configuration now is ended so let’s start the services!
First of all restart the networking in order to apply the modification

root@raspberrypi:~# /etc/init.d/networking restart

Then start or restart if running the DHCP Server service

root@raspberrypi:~# /etc/init.d/isc-dhcp-server restart

Start hostapd

root@raspberrypi:~# /etc/init.d/hostapd restart

We are done! Now you should see your Wi-FI Network and able to connect to it. You can also use now use multiple devices through your 3G/4G USB key.