Building Elastix MT via RPM Repo CentOS 6.7 for this build.

#!/bin/bash

# SAM's Elastix MT on CentOS 6 Installation and Build Script
# http://mangolassi.it/topic/6243/building-elastix-mt-via-rpm-repo
# Report any issues or questions on that thread.

yum -y install epel-release
yum -y install fail2ban htop sysstat glances wget screen
yum -y update
cd /tmp
wget http://sourceforge.net/projects/elastix/files/Elastix%20PBX%20Appliance%20Software/3.0.0/latest/Elastix-3.0.0-Stable-x86_64-bin-10nov2014.iso/download
mv download elastixmt.iso
mkdir -p /mnt/elastixmt
mount -o loop /tmp/elastixmt.iso /mnt/elastixmt
cat > /etc/yum.repos.d/Elastix.repo <<EOF
[Elastix-cd]
name=Elastix-cd
baseurl=file:///mnt/elastixmt/
gpgcheck=0
enabled=1
EOF
cd /mnt/elastixmt/Elastix
for i in $(ls); do yum -y install $i; done
for i in $(ls); do yum -y install $i; done
/etc/init.d/mysqld start
/etc/init.d/elastix-firstboot start && reboot

 

Install Cacti on CentOS 6/7

Step 1 – Prerequisites

First we need to install some of the software packages needed for Cacti to run properly. Software which is not included or enabled in the base CentOS 6 installation are:

  • rrdtool
  • apache
  • mysql
  • cron
  • gcc

Let’s use yum to get these installed.

Centos 6:
yum -y install mysql-server php php-cli php-mysql net-snmp-utils rrdtool \
  php-snmp gcc mysql-devel net-snmp-devel autoconf automake libtool dos2unix wget help2man

Centos 7:
yum -y install mariadb-server php php-cli php-mysql net-snmp-utils rrdtool \
  php-snmp gcc mariadb-devel net-snmp-devel autoconf automake libtool dos2unix wget help2man

gcc and the devel packages are required for the installation of spine, hence that’s why we include it here.

Now let’s make sure that our webserver and the database are automatically starting up after a reboot. Use the following commands to enable these:

CentOS 6:
chkconfig httpd on
chkconfig mysqld on
chkconfig crond on

CentOS 7:
systemctl enable httpd.service
systemctl enable mariadb.service
systemctl enable crond.service

Now that we did make sure that these services start after a reboot, let’s start them manually now in order to continue the installation. Cron may already be running so don’t panic if you don’t see the usual start message:

CentOS 6:
service httpd restart
service mariadb restart
service crond restart

CentOS 7:
systemctl restart httpd.service
systemctl restart mariadb.service
systemctl restart crond.service

 

Step 2 – Cacti Files

Let’s now move to the actualy installation of Cacti. First we need to download and extract it. As of version 0.8.8, a fully patched Cacti including the Plugin Architecture (PIA) is officially available, so we’re downloading that one:

cd /var/www/html
wget http://www.cacti.net/downloads/cacti-0.8.8g.tar.gz
tar -xzvf cacti-0.8.8g.tar.gz

I usually suggest to create a symbolic link to the newly created directory “cacti-0.8.8b”. This will make upgrades to never Cacti versions easier:

ln -s cacti-0.8.8g cacti

Step 3 – Cron and file permissions

Cacti uses cron (scheduled task) in order to execute its polling process.  It’s always a good idea to run this under a special user. Let’s create the system “cacti” user now:

adduser -d /var/www/html/cacti -s /sbin/nologin cacti

Having done that, we can now  add a new cron entry to your system for a 5 minute polling interval using the following command:

echo "*/5 * * * * cacti php /var/www/html/cacti/poller.php &>/dev/null" >> /etc/cron.d/cacti

Finally, we also need to make sure that the permissions on the log and rra directories are set correctly:

cd /var/www/html/cacti
chown -R cacti.apache rra log  
chmod 775 rra log

 

Step 4 – Cacti Database

Now that we have extracted the cacti files, we can move on preparing the database for the final installation step. Your first step should be securing the mysql database. The following command will help you with this task on a CentOS system. Make sure to select a strong password for root, e.g. MyN3wpassw0rd

/usr/bin/mysql_secure_installation

Let’s create a new database and assign a special user to it:

mysqladmin -u root -p create cacti
mysql -p cacti < /var/www/html/cacti/cacti.sql
mysql -u root -p

With the last command, you should be seing a mysql prompt where you can enter mysql commands. Here we are going to create the special cacti user. That user only needs to be able to connect from the local system and should have a strong password as well. Enter the following commands and make sure to replace the password:

GRANT ALL ON cacti.* TO cactiuser@localhost IDENTIFIED BY 'MyV3ryStr0ngPassword';
flush privileges;
exit

We now have the cacti files and the cacti database setup. The last step before moving to the web-based installer is setting the database credentials within the Cacti config file:

cd /var/www/html/cacti/include/
vi config.php

Change the $database_ lines to fit your new settings:

$database_type = "mysql";
$database_default = "cacti";
$database_hostname = "localhost";
$database_username = "cactiuser";
$database_password = "MyV3ryStr0ngPassword";
$database_port = "3306";
$database_ssl = false;

Depending on your installation, you should also uncomment the following line. In our example we have to make sure the following line is there:

$url_path = "/cacti/";

Step 5 – Adding firewall rules

The following settings will add access rules to http and https from outside:

Centos 7:
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --reload

Step 6 – Important PHP Settings

The default PHP installation usually has not configured the correct timezone or php error reporting. While not required to run Cacti, it’s highly recommended to enable error reporting to syslog for troubleshooting issues with plugins or other scripts.

The following lines need to be enabled/configued in your /etc/php.ini file:

; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Europe/Berlin

and

; Log errors to syslog (Event Log on NT, not valid in Windows 95).
error_log = syslog

Step 7 – Running the Web-based installer

Let’s move on to the web-based installer.

Login with admin/admin and you’re ready to go !

Please go to “Console -> System Utilities” and click on “Rebuild Poller Cache” after the first login!

 

How To Install and Configure SNMP on CentOS

Introduction

SNMP, or Simple Network Management Protocol, is widely used to communicate with and monitor network devices, servers, and more, all via IP. In this case, we’ll be installing an SNMP agent on a CentOS 6.5 server, which will allow for collection of data from our server, and make the information available to a remote SNMP manager.

Pre-Flight Check

  • These instructions are intended for installing SNMP and doing a very basic configuration.
  • I’ll be working from a Liquid Web Core Managed CentOS 6.5 server, and I’ll be logged in as root.

Install SNMP and SNMP Utilities

Installing SNMP and some optional SNMP utilities is as simple as running one command:

yum -y install net-snmp net-snmp-utils

Add a Basic Configuration for SNMP

Now, let’s take the default SNMP configuration file, /etc/snmp/snmpd.conf and move it to an alternate location, /etc/snmp/snmpd.conf.orig.

mv /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.orig

And now we’ll create a new /etc/snmp/snmpd.conf:

vim /etc/snmp/snmpd.conf

For a refresher on editing files with vim see: New User Tutorial: Overview of the Vim Text Editor

Insert the following text into the new /etc/snmp/snmpd.conf

# Map 'idv90we3rnov90wer' community to the 'ConfigUser'
# Map '209ijvfwer0df92jd' community to the 'AllUser'
#       sec.name        source          community
com2sec ConfigUser      default         idv90we3rnov90wer
com2sec AllUser         default         209ijvfwer0df92jd
# Map 'ConfigUser' to 'ConfigGroup' for SNMP Version 2c
# Map 'AllUser' to 'AllGroup' for SNMP Version 2c
#                       sec.model       sec.name
group   ConfigGroup     v2c             ConfigUser
group   AllGroup        v2c             AllUser
# Define 'SystemView', which includes everything under .1.3.6.1.2.1.1 (or .1.3.6.1.2.1.25.1)
# Define 'AllView', which includes everything under .1
#                       incl/excl       subtree
view    SystemView      included        .1.3.6.1.2.1.1
view    SystemView      included        .1.3.6.1.2.1.25.1.1
view    AllView         included        .1
# Give 'ConfigGroup' read access to objects in the view 'SystemView'
# Give 'AllGroup' read access to objects in the view 'AllView'
#                       context model   level   prefix  read            write   notify
access  ConfigGroup     ""      any     noauth  exact   SystemView      none    none
access  AllGroup        ""      any     noauth  exact   AllView         none    none

The above text is noted with basic information on the function of each configuration line. In short, we’re creating two scenarios for polling information from SNMP version 2c.

Note: SNMPv2c contains some security enhancements over SNMPv1 but uses the existing SNMPv1 administration structure, which is “community” based. Areas of improvement include: transport mappings, protocol packet types, and MIB structure elements.

In the first scenario: ConfigUser is assigned to ConfigGroup and may only use SNMP security model 2c,ConfigGroup can use the SystemView, SystemView is assigned to two OID sub-trees, and all of this is referenced in an SNMP poll by the secret, and unique community string idv90we3rnov90wer.

In the second scenario: AllUser is assigned to AllGroup and may only use SNMP security model 2c,AllGroup can use the AllView, AllView is assigned to the entire OID tree, and all of this is referenced in an SNMP poll by the secret, and unique community string 209ijvfwer0df92jd.

Important Tip: Be ABSOLUTELY SURE that you choose a unique community string and replace the community strings in the above examples. Keep each secret, and keep each safe.

Exit vim, and restart the SNMP service to reload the new configuration file:

service snmpd restart

Configure SNMP to start when the server boots:

chkconfig snmpd on

Test the SNMP Configuration

Now let’s test the SNMP configuration… try running the following two commands:

snmpwalk -v 2c -c idv90we3rnov90wer -O e 127.0.0.1
snmpwalk -v 2c -c 209ijvfwer0df92jd -O e 127.0.0.1

Note: The default port for SNMP is 161 and 162. If you’re going to connect to SNMP from a remote server, be sure your server’s firewall has the appropriate ports open.

The result for your first command should be about 33 lines, and contain some basic system information. The result for the second command should contain a lot more information about your system, and will likely be thousands of lines.

How To Configure Nginx as a Web Server and Reverse Proxy for Apache on One Ubuntu 14.04 Droplet

Introduction

Apache and Nginx are two popular open source web servers often used with PHP. It can be useful to run both of them on the same virtual machine when hosting multiple websites which have varied requirements. The general solution for running two web servers on a single system is to either use multiple IP addresses or different port numbers.

Droplets which have both IPv4 and IPv6 addresses can be configured to serve Apache sites on one protocol and Nginx sites on the other, but this isn’t currently practical, as IPv6 adoption by ISPs is still not widespread. Having a different port number like 81 or 8080 for the second web server is another solution, but sharing URLs with port numbers (such as http://example.com:81) isn’t always reasonable or ideal.

This tutorial will show you how to configure Nginx as both a web server and as a reverse proxy for Apache – all on one Droplet. Depending on the web application, code changes might be required to keep Apache reverse-proxy-aware, especially when SSL sites are configured. To ensure this, we will install an Apache module named mod_rpaf which rewrites certain environment variables so it appears that Apache is directly handling requests from web clients.

We will host four domain names on one Droplet. Two will be served by Nginx: example.com (the default virtual host) and sample.org. The remaining two, foobar.net and test.io, will be served by Apache.

Prerequisites

  • A new Ubuntu 14.04 Droplet.
  • A standard user account with sudo privileges. You can set up a standard account by following Steps 2 and 3 of the Initial Server Setup with Ubuntu 14.04.
  • The desired domain names should point to your Droplet’s IP address in the DigitalOcean control panel. See Step 3 of How To Set Up a Host Name with DigitalOcean for an example of how to do this. If you host your domains’ DNS elsewhere, you should create appropriate A records there instead.

Optional References

This tutorial requires basic knowledge of virtual hosts in Apache and Nginx, and SSL certificate creation and configuration. For more information on these topics, see the following articles.

Step 1 — Installing Apache and PHP5-FPM

In addition to Apache and PHP-FPM, we must also install the PHP FastCGI Apache module. This islibapache2-mod-fastcgi, available in Ubuntu’s multiverse repository, which must first be enabled in the sources.list file.

sudo nano /etc/apt/sources.list

Find the following lines and uncomment them by removing the hash symbol (#) at the beginning.

# deb http://mirrors.digitalocean.com/ubuntu trusty multiverse

 . . .

# deb http://mirrors.digitalocean.com/ubuntu trusty-updates multiverse

That should leave you with what’s shown below.

 deb http://mirrors.digitalocean.com/ubuntu trusty multiverse

 . . .

 deb http://mirrors.digitalocean.com/ubuntu trusty-updates multiverse

Save the file and update the apt repository.

sudo apt-get update

Then install the necessary packages.

sudo apt-get install apache2 libapache2-mod-fastcgi php5-fpm

Step 2 — Configuring Apache and PHP5-FPM

In this step we will change Apache’s port number to 8080 and configure it to work with PHP5-FPM using the mod_fastcgi module. Edit the Apache configuration file and change the port number of Apache.

sudo nano /etc/apache2/ports.conf

Find the following line:

Listen 80

Change it to:

Listen 8080

Save and exit ports.conf.

Note: Web servers are generally set to listen on 127.0.0.1:8080 when configuring a reverse proxy but doing so would set the value of PHP’s environment variable SERVER_ADDR to the loopback IP address instead of the server’s public IP. Our aim is to set up Apache in such a way that its websites do not see a reverse proxy in front of it. So, we will configure it to listen on 8080 on all IP addresses.

Next we’ll edit the default virtual host file of Apache. The <VirtualHost> directive in this file is set to serve sites only on port 80.

sudo nano /etc/apache2/sites-available/000-default.conf

The first line should be:

<VirtualHost *:80>

Change it to:

<VirtualHost *:8080>

Save the file and reload Apache.

sudo service apache2 reload

Verify that Apache is now listening on 8080.

sudo netstat -tlpn

The output should look like below, with apache2 listening on :::8080.

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address     Foreign Address      State    PID/Program name
tcp        0      0 0.0.0.0:22        0.0.0.0:*            LISTEN   1086/sshd
tcp6       0      0 :::8080           :::*                 LISTEN   4678/apache2
tcp6       0      0 :::22             :::*                 LISTEN   1086/sshd

Step 3 — Configuring Apache to Use mod_fastcgi

Apache works with mod_php by default, but it requires additional configuration to work with PHP5-FPM.

Note: If you are trying this tutorial on an existing installation of LAMP with mod_php, disable it first with:

sudo a2dismod php5

We will be adding a configuration block for mod_fastcgi which depends on mod_action. mod-actionis disabled by default, so we first need to enable it.

sudo a2enmod actions

Find out which version of Apache is installed on your Droplet with:

sudo apache2 -v

Edit the fastcgi configuration file accordingly. These configuration directives pass requests for .phpfiles to the PHP5-FPM UNIX socket.

sudo nano /etc/apache2/mods-enabled/fastcgi.conf

Add the following lines to the bottom of the <IfModule mod_fastcgi.c> . . . </IfModule> block for Apache 2.4:

 AddType application/x-httpd-fastphp5 .php
 Action application/x-httpd-fastphp5 /php5-fcgi
 Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
 FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization
 <Directory /usr/lib/cgi-bin>
  Require all granted
 </Directory>

Apache 2.2 does not require the <Directory> section so add the following:

 AddType application/x-httpd-fastphp5 .php
 Action application/x-httpd-fastphp5 /php5-fcgi
 Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
 FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization

When finished in fastcgi.conf, do a configuration test.

sudo apachectl -t

Reload Apache if Syntax OK is displayed. If you see the warning Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message., that’s fine. It doesn’t affect us now.

sudo service apache2 reload

Step 4 — Verifying PHP Functionality

Check if PHP works by creating a phpinfo() file and accessing it from your web browser.

echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php

To see the file in a browser, go to http://111.111.111.111:8080/info.php but using your Droplet’s IP address. This will give you a list of configuration specifications PHP is using.

phpinfo Server API

phpinfo PHP Variables

At the top of the page, check that Server API says FPM/FastCGI. About two-thirds of the way down the page, the PHP Variables section will tell you the SERVER_SOFTWARE is Apache on Ubuntu. These confirm that mod_fastcgi is active and Apache is using PHP5-FPM to process PHP files.

Step 5 — Creating Virtual Hosts for Apache

We will create two Apache virtual host files for the domains foobar.net and test.io. This begins with creating document root directories for both sites.

sudo mkdir -v /var/www/{foobar.net,test.io}

Now we will add two files to each directory for testing after setup is complete.

First we’ll create an index file for each site.

echo "<h1 style='color: green;'>Foo Bar</h1>" | sudo tee /var/www/foobar.net/index.html
echo "<h1 style='color: red;'>Test IO</h1>" | sudo tee /var/www/test.io/index.html

Then, a phpinfo() file.

echo "<?php phpinfo(); ?>" | sudo tee /var/www/foobar.net/info.php
echo "<?php phpinfo(); ?>" | sudo tee /var/www/test.io/info.php

Create the virtual host file for the foobar.net domain.

sudo nano /etc/apache2/sites-available/foobar.net.conf

Place the following directive in it:

<VirtualHost *:*>
    ServerName foobar.net
    ServerAlias www.foobar.net
    DocumentRoot /var/www/foobar.net
    <Directory /var/www/foobar.net>
        AllowOverride All
    </Directory>
</VirtualHost>

Save and close the file. Then do the same for test.io.

sudo nano /etc/apache2/sites-available/test.io.conf
<VirtualHost *:*>
    ServerName test.io
    ServerAlias www.test.io
    DocumentRoot /var/www/test.io
    <Directory /var/www/test.io>
        AllowOverride All
    </Directory>
</VirtualHost>

Note 1: AllowOverride All enables .htaccess support.

Note 2: These are only the most basic directives. For a complete guide on setting up virtual hosts in Apache, see How To Set Up Apache Virtual Hosts on Ubuntu 14.04 LTS.

Now that both Apache virtual hosts are set up, enable the sites using the a2ensite command. This creates a symbolic link to the virtual host file in the sites-enabled directory.

sudo a2ensite foobar.net
sudo a2ensite test.io

Check Apache for configuration errors again.

sudo apachectl -t

Reload it if Syntax OK is displayed.

sudo service apache2 reload

To confirm the sites are working, open http://foobar.net:8080 and http://test.io:8080 in your browser and verify they’re displaying their index.html files.

You should see:

foobar.net index page

test.io index page

Also, check if PHP is working by accessing the info.php files: http://foobar.net:8080/info.php andhttp://test.io:8080/info.php.

You should see the same PHP configuration spec list on each site as you saw in Step 1. We now have two websites hosted on Apache at port 8080.

Step 6 — Installing and Configuring Nginx

In this step we will install Nginx and configure the domains example.com and sample.org as Nginx’s virtual hosts. For a complete guide on setting up virtual hosts in Nginx, see How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 14.04 LTS.

Install Nginx.

sudo apt-get install nginx

Then remove the default virtual host’s symlink.

sudo rm /etc/nginx/sites-enabled/default

Now we’ll create virtual hosts for Nginx. First make document root directories for both the websites:

sudo mkdir -v /usr/share/nginx/{example.com,sample.org}

As we did with Apache’s virtual hosts, we’ll again create index and phpinfo() files for testing after setup is complete.

echo "<h1 style='color: green;'>Example.com</h1>" | sudo tee /usr/share/nginx/example.com/index.html
echo "<h1 style='color: red;'>Sample.org</h1>" | sudo tee /usr/share/nginx/sample.org/index.html
echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/example.com/info.php
echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/sample.org/info.php

Now create a virtual host file for the domain example.com.

sudo nano /etc/nginx/sites-available/example.com

Nginx calls server {. . .} areas of a configuration file server blocks. Create a server block for the primary virtual host, example.com. The default_server configuration directive makes this the default virtual host which processes HTTP requests that do not match any other virtual host.

Paste the following into the file for example.com:

server {
    listen 80 default_server;

    root /usr/share/nginx/example.com;
    index index.php index.html index.htm;

    server_name example.com www.example.com;
    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

Save and close the file. Now create a virtual host file for Nginx’s second domain, sample.org.

sudo nano /etc/nginx/sites-available/sample.org

The server block for sample.org should look like this:

server {
    root /usr/share/nginx/sample.org;
    index index.php index.html index.htm;

    server_name sample.org www.sample.org;
    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

Save and close the file. Then enable both the sites by creating symbolic links to the sites-enableddirectory.

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
sudo ln -s /etc/nginx/sites-available/sample.org /etc/nginx/sites-enabled/sample.org

Do an Nginx configuration test:

sudo service nginx configtest

Then reload Nginx if OK is displayed.

sudo service nginx reload

Now acccess the phpinfo() file of your Nginx virtual hosts in a web browser byhttp://example.com/info.php and http://sample.org/info.php. Look under the PHP Variablessection again.

Nginx PHP Variables

[“SERVER_SOFTWARE”] should say nginx, indicating that the files were directly served by Nginx.[“DOCUMENT_ROOT”] should point to the directory you created earlier in this step for each Nginx site.

At this point, we have installed Nginx and created two virtual hosts. Next we will set up an additional virtual host to proxy requests meant for domains hosted on Apache.

Step 7 — Configuring Nginx for Apache’s Virtual Hosts

In this section we will create an additional Nginx virtual host with multiple domain names in theserver_name directives. Requests for these domain names will be proxied to Apache.

Create a new Nginx virtual host file:

sudo nano /etc/nginx/sites-available/apache

Add the code block below. This specifies the names of both Apache virtual host domains, and proxies their requests to Apache. Remember to use the public IP address in proxy_pass.

server {
    listen 80;
    server_name foobar.net www.foobar.net test.io www.test.io;

    location / {
        proxy_pass http://111.111.111.111:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Save the file and enable this new virtual host by creating a symbolic link.

sudo ln -s /etc/nginx/sites-available/apache /etc/nginx/sites-enabled/apache

Do a configuration test:

sudo service nginx configtest

Reload Nginx if OK is displayed.

sudo service nginx reload

Open the browser and access the http://foobar.net/info.php on one of Apache’s domain names. Scroll down to the PHP Variables section and check the values displayed.

phpinfo of Apache via Nginx

The variables SERVER_SOFTWARE and DOCUMENT_ROOT should confirm that this request was handled by Apache. The variables HTTP_X_REAL_IP and HTTP_X_FORWARDED_FOR were added by Nginx and should show the public IP address of the computer you’re accessing the URL from in your browser.

We have successfully setup Nginx to proxy requests for specific domains to Apache. The next step is to configure Apache to set variables REMOTE_ADDR as if it were handling these requests directly.

Step 8 — Installing and Configuring mod_rpaf

In this step we will install an Apache module named mod_rpaf which rewrites the values ofREMOTE_ADDR, HTTPS and HTTP_PORT based on the values provided by a reverse proxy. Without this module, some PHP applications would require code changes to work seamlessly from behind a proxy. This module is present in Ubuntu’s repository as libapache2-mod-rpaf but is outdated and doesn’t support certain configuration directives. Instead, we will install it from source.

Install the packages needed to compile and build the module:

sudo apt-get install unzip build-essential apache2-threaded-dev

Download the latest stable release from GitHub.

wget https://github.com/gnif/mod_rpaf/archive/stable.zip

Extract it with:

unzip stable.zip

Change into the working directory.

cd mod_rpaf-stable

Then compile and install the module.

sudo make
sudo make install

Create a file in the mods-available directory which loads the rpaf module.

sudo nano /etc/apache2/mods-available/rpaf.load

Add the following line to the file:

LoadModule rpaf_module /usr/lib/apache2/modules/mod_rpaf.so

Create another file in this directory. This will contain the configuration directives.

sudo nano /etc/apache2/mods-available/rpaf.conf

Add the following code block, making sure to add the IP address of your Droplet.

<IfModule mod_rpaf.c>
        RPAF_Enable             On
        RPAF_Header             X-Real-Ip
        RPAF_ProxyIPs           111.111.111.111
        RPAF_SetHostName        On
        RPAF_SetHTTPS           On
        RPAF_SetPort            On
</IfModule>

Here’s a brief description of each directive. See the mod_rpaf README file for more information.

  • RPAF_Header – The header to use for the client’s real IP address.
  • RPAF_ProxyIPs – The proxy IP to adjust HTTP requests for.
  • RPAF_SetHostName – Updates the vhost name so ServerName and ServerAlias work.
  • RPAF_SetHTTPS – Sets the HTTPS environment variable based on the value contained in X-Forwarded-Proto.
  • RPAF_SetPort – Sets the SERVER_PORT environment variable. Useful for when Apache is behind a SSL proxy.

Save rpaf.conf and enable the module.

sudo a2enmod rpaf

This creates symbolic links of the files rpaf.load and rpaf.conf in the mods-enabled directory. Now do a configuration test.

sudo apachectl -t

Reload Apache if Syntax OK is returned.

sudo service apache2 reload

Access one of Apache’s websites’ phpinfo() page on your browser and check the PHP Variablessection. The REMOTE_ADDR variable will now also be that of your local computer’s public IP address.

Step 9 — Setting Up HTTPS Websites (Optional)

In this step we will configure SSL certificates for both the domains hosted on Apache. Nginx supports SSL termination so we can set up SSL without modifying Apache’s configuration files. The mod_rpaf module ensures the required environment variables are set on Apache to make applications work seamlessly behind a SSL reverse proxy.

Create a directory for the SSL certificates and their private keys.

sudo mkdir /etc/nginx/ssl

For this article we will use self-signed SSL certificates with a validity of 10 years. Generate self-signed certificates for both foobar.net and test.io.

sudo openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/nginx/ssl/foobar.net-key.pem -out /etc/nginx/ssl/foobar.net-cert.pem -days 3650 -nodes
sudo openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/nginx/ssl/test.io-key.pem -out /etc/nginx/ssl/test.io-cert.pem -days 3650 -nodes

Each time, you will be prompted for certificate identification details.

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean Inc
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:

Now open the apache virtual host file that proxies requests from Nginx to Apache.

sudo nano /etc/nginx/sites-available/apache

Since we have separate certificates and keys for each domain we need to have separate server { . . . } blocks for each domain. You should delete it’s current contents and when finished, your apachevhost file should look similar to below.

server {
    listen 80;
    listen 443 ssl;
    server_name test.io www.test.io;

    ssl on;
    ssl_certificate /etc/nginx/ssl/test.io-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/test.io-key.pem;

    location / {
        proxy_pass http://111.111.111.111:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    listen 443 ssl;
    server_name foobar.net www.foobar.net;

    ssl on;
    ssl_certificate /etc/nginx/ssl/foobar.net-cert.pem;
    ssl_certificate_key /etc/nginx/ssl/foobar.net-key.pem;

    location / {
        proxy_pass http://111.111.111.111:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Save the file and perform a configuration test.

sudo service nginx configtest

Reload Nginx if the test succeeds.

sudo service nginx reload

Access one of Apache’s domains over the browser with the https:// prefix:https://foobar.net/info.php

phpinfo ssl

Look in the PHP Variables section. The variable SERVER_PORT has been set to 443 and HTTPS set to on, as though Apache was directly accessed over HTTPS. With these variables set, PHP applications do not have to be specially configured to work behind a reverse proxy.

Step 10 — Blocking Direct Access to Apache (Optional)

Since Apache is listening on port 8080 on the public IP address, it is accessible by everyone. It can be blocked by working the following IPtables command into your firewall rule set.

sudo iptables -I INPUT -p tcp --dport 8080 ! -s 111.111.111.111 -j REJECT --reject-with tcp-reset

Be sure to use your Droplet’s IP address in place of the example in red. Once port 8080 is blocked in your firewall, test that Apache is unreachable on it. Open your web browser and try accessing one of Apache’s domain names on port 8080. For example: http://example.com:8080

The browser should display an “Unable to connect” or “Webpage is not available” error message. With the IPtables tcp-reset option in place, an outsider would see no difference between port 8080 and a port that doesn’t have any service on it.

Note: IPtables rules do not survive a system reboot by default. There are multiple ways to preserve IPtables rules, but the easiest is to use iptables-persistent in Ubuntu’s repository.

Step 11 — Serving Static Files Using Nginx (Optional)

When Nginx proxies requests for Apache’s domains, it sends every file request to domain to Apache. Nginx is faster than Apache in serving static files like images, JavaScript and style sheets. So in this section we will configure Nginx’s apache virtual host file to directly serve static files and just send PHP requests to Apache.

Open the apache virtual host file.

sudo nano /etc/nginx/sites-available/apache

Add two additional location blocks to each server block as shown in red in the code block below.

server {
    listen 80;
    server_name test.io www.test.io;
    root /var/www/test.io;
    index index.php index.htm index.html;

    location / {
     try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        proxy_pass http://111.111.111.111:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~ /\. {
     deny all;
    }
}

server {
    listen 80;
    server_name foobar.net www.foobar.net;
    root /var/www/foobar.net;
    index index.php index.htm index.html;

    location / {
     try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        proxy_pass http://111.111.111.111:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~ /\. {
     deny all;
    }
}

The try_files directive makes Nginx to look for files in the document root and directly serve them. If the file has a .php extension, the request is passed to Apache. Even if the file is not found in thedocument root, the request is passed on to Apache so that application features like permalinks work without problems.

Safe the file and perform a configuration test.

sudo service nginx configtest

Reload Nginx if the test succeeds.

sudo service nginx reload

To verify this is working, you can examine Apache’s log files in /var/log/apache2 and see the GET requests for the index.php files of test.io and foobar.net. The only caveat of this setup is that Apache will not be able to restrict access to static files. Access control for static files would need to be configured in Nginx’s apache virtual host file.

Warning: The location ~ /\. directive is very important to include. This prevents Nginx from printing the contents of files like .htaccess and .htpasswd.

Conclusion

Having completed this tutorial, you should now have one Ubuntu Droplet with Nginx servingexample.com and sample.org, along with Apache serving foobar.net and test.io. Though Nginx is acting as a reverse-proxy for Apache, Nginx’s proxy service is transparent and connections to Apache’s domains appear be served directly from Apache itself.

Source : https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-web-server-and-reverse-proxy-for-apache-on-one-ubuntu-14-04-droplet

 

Apple Push Notification Services in iOS 6 Tutorial: Part 1/2

Apple Push Notification Services in iOS 6 Tutorial: Part 1/2

If you’re new here, you may want to subscribe to my RSS feed or follow me on Twitter. Thanks for visiting!

Learn how to add Push Notifications into your iPhone app!

Update 4/12/2013: Fully updated for iOS 6 (original post by Matthijs Hollemans, update by Ali Hafizji).

In iOS, apps can’t do a lot in the background. Apps are only allowed to do limited set of activities so battery life is conserved.

But what if something interesting happens and you wish to let the user know about this, even if they’re not currently using your app?

For example, maybe the user received a new tweet, their favorite team won the game, or their dinner is ready. Since the app isn’t currently running, it cannot check for these events.

Luckily, Apple has provided a solution to this. Instead of your app continuously checking for events or doing work in the background, you can write a server-side component to do this instead.

And when an event of interest occurs, the server-side component can send the app a push notification! There are three things a push notification can do:

  • Display a short text message
  • Play a brief sound
  • Set a number in a badge on the app’s icon

You can combine these however you see fit; for example, play a sound and set the badge but not display a message.

In this 2-part tutorial series, you’ll get to try this out for yourself by making a simple app that uses APNS (Apple push notification service)!

In this first part, you’ll learn how to configure your app to receive push notifications and receive a test message.

This tutorial is for intermediate or advanced iOS developers. If you are still a beginner to iOS, you should check out some of the other tutorials on this site first. Also, it’s highly recommended that you review these two tutorials first (or have equivalent knowledge):

Without further ado, let’s push through this!

Getting Started: Brief Overview

Getting push to work for your app takes quite a bit of effort. This is a puzzle with many pieces. Here is an overview:

Apple Push Notification Services (APNS) Overview

  1. An app enables push notifications. The user has to confirm that he wishes to receive these notifications.
  2. The app receives a “device token”. You can think of the device token as the address that push notifications will be sent to.
  3. The app sends the device token to your server.
  4. When something of interest to your app happens, the server sends a push notification to the Apple Push Notification Service, or APNS for short.
  5. APNS sends the push notification to the user’s device.

When the user’s device receives the push notification, it shows an alert, plays a sound and/or updates the app’s icon. The user can launch the app from the alert. The app is given the contents of the push notification and can handle it as it sees fit.

Are push notifications still worth it now that we have local notifications and multitasking? You bet!

Local notifications are limited to scheduling timed events and unlimited background processing is only available to apps that do VOIP, navigation or background audio. If you want to notify the users of your app about external events while the app is closed, you still need push notifications.

In this tutorial, I will explain in detail how the push notification system works and how to build push into your own app. There is a lot to explain, so take your time to let it all sink in.

What You Need for Push Notifications

To add push notifications to your app, you need:

An iPhone or iPad. Push notifications do not work in the simulator, so you will need to test on the device.

An iOS Developer Program membership. You need to make a new App ID and provisioning profile for each app that uses push, as well as an SSL certificate for the server. You do this at the iOS Provisioning Portal.

If you want to follow along with the examples in this tutorial, you will need to create your own provisioning profile and SSL certificate; you cannot use mine. Because it’s important to get the certificate right, I’ll explain the detailed steps on how to obtain one.

A server that is connected to the internet. Push notifications are always sent by a server. For development you can use your Mac as the server (which you’ll do in this tutorial) but for production use, you need at least something like a VPS (Virtual Private Server).

A cheap shared hosting account is not good enough. You need to be able to run a background process on the server, install an SSL certificate, and be able to make outgoing TLS connections on certain ports.

Most shared hosting providers do not let you do this, although they might if you ask. However, I really recommend using a VPS host such as Linode.

Anatomy of a Push Notification

Your server is responsible for creating the push notification messages, so it’s useful to know what they look like.

A push notification is a short message that consists of the device token, a payload, and a few other bits and bytes. The payload is what you are interested in, as that contains the actual data you will be sending around.

Your server should provide the payload as a JSON dictionary. The payload for a simple push message looks like this:

{
	"aps":
	{
		"alert": "Hello, world!",
		"sound": "default"
	}
}

For the JSON uninitiated, a block delimited by curly { } brackets contains a dictionary that consists of key/value pairs (just like an NSDictionary).

The payload is a dictionary that contains at least one item, “aps”, which itself is also a dictionary. In our example, “aps” contains the fields “alert” and “sound”. When this push notification is received, it shows an alert view with the text “Hello, world!” and plays the standard sound effect.

There are other items you can add to the “aps” section to configure the notification. For example:

{
	"aps":
	{
		"alert":
		{
			"action-loc-key": "Open",
			"body": "Hello, world!"
		},
		"badge": 2
	}
}

Now “alert” is a dictionary of its own. The “action-loc-key” provides an alternative text for the “View” button. The “badge” field contains the number that will be shown on the application icon. This notification will not play a sound.

There are many more ways to configure the JSON payload. You can change the sound that is played, you can provide localized text, and you can add fields of your own. For more information, check out the officialLocal and Push Notification Programming Guide.

Push notifications are intended to be small; the payload size can be no more than 256 bytes. That leaves you about as much room as fits in an SMS message or a tweet. A smart push server won’t waste space on newlines and whitespace and generates something that looks like:

{"aps":{"alert":"Hello, world!","sound":"default"}}

It’s less easy to read for us humans, but it saves enough bytes to make it worth it. Push notifications whose payload exceeds 256 bytes will not be accepted by APNS.

Push Notification Gotchas

Push Notifications Are Unreliable!

They are not reliable! There is no guarantee that push notifications will actually be delivered, even if the APNS server accepted them.

As far as your server is concerned, push notifications are fire-and-forget; there is no way to find out what the status of a notification is after you’ve sent it to APNS. The delivery time may also vary, from seconds up to half an hour.

Also, the user’s iPhone may not be able to receive push notifications all the time. They could be on a WiFi network that does not allow connections to be made to APNS because the required ports are blocked. Or the phone could be turned off.

APNS will try to deliver the last notification it received for that device when it comes back online, but it will only try for a limited time. Once it times out, the push notification will be lost forever!

After looking at the APNS Server Bill

They can be expensive! Adding push functionality to your app is fairly easy and inexpensive if you own the data, but can be expensive if you have a lot of users or data you need to poll.

For example, it’s no problem if you want to notify your users when the contents of your own RSS feed change. Because you control that RSS feed and know when it changes — when you update the content on your web site — your server can send out the notifications at the right moment.

But what if your app is an RSS feed reader that allows users to put in their own URLs? In that case you need to come up with some mechanism to detect updates to those feeds.

In practice this means your server will need to continuously poll those feeds for changes. If you have a lot of users, you may have to install a bunch of new servers to handle all that processing and bandwidth. For apps such as these, push can become quite expensive and may not be worth it.

OK, enough theory. It’s time to learn how to do this push thing. Before we can get to the good stuff – programming! – there is some boring set-up work to be done on the iOS Provisioning Portal, so let’s get that over with as quickly as possible.

Provisioning Profiles and Certificates, Oh My!

APNS needs a certificate!

To enable push notifications in your app, it needs to be signed with a provisioning profile that is configured for push. In addition, your server needs to sign its communications to APNS with an SSL certificate.

The provisioning profile and SSL certificate are closely tied together and are only valid for a single App ID. This is a protection that ensures only your server can send push notifications to instances of your app, and no one else.

As you know, apps use different provisioning profiles for development and distribution. There are also two types of push server certificates:

  • Development. If your app is running in Debug mode and is signed with the Development provisioning profile (Code Signing Identity is “iPhone Developer”), then your server must be using the Development certificate.
  • Production. Apps that are distributed as Ad Hoc or on the App Store (when Code Signing Identify is “iPhone Distribution”) must talk to a server that uses the Production certificate. If there is a mismatch between these, push notifications cannot be delivered to your app.

In this tutorial, you won’t bother with the distribution profiles and certificates and just use the ones for development.

Generating the Certificate Signing Request (CSR)

Remember how you had to go to the iOS Provisioning Portal and make a Development Certificate after you signed up for the iOS Developer Program? If so, then these next steps should be familiar. Still, I advise you to follow them exactly. Most of the problems people have with getting push notifications to work are due to problems with the certificates.

Digital certificates are based on public-private key cryptography. You don’t need to know anything about cryptography to use certificates, but you do need to be aware that a certificate always works in combination with a private key.

The certificate is the public part of this key pair. It is safe to give it to others, which is exactly what happens when you communicate over SSL. The private key, however, should be kept… private. It’s a secret. Your private key is nobody’s business but your own. It’s important to know that you can’t use the certificate if you don’t have the private key.

Whenever you apply for a digital certificate, you need to provide a Certificate Signing Request, or CSR for short. When you create the CSR, a new private key is made that is put into your keychain. You then send the CSR to a certificate authority (in this case that is the iOS Developer Portal), which will generate the SSL certificate for you based on the information in the CSR.

Open Keychain Access on your Mac (it is in Applications/Utilities) and choose the menu option Request a Certificate from a Certificate Authority….

Requesting a certificate with Keychain Access

If you do not have this menu option or it says “Request a Certificate from a Certificate Authority with key”, then download and install the WWDR Intermediate Certificate first. Also make sure no private key is selected in the main Keychain Access window.

You should now see the following window:

Generating a certificate sign request with Keychain Access

Enter your email address here. I’ve heard people recommended you use the same email address that you used to sign up for the iOS Developer Program, but it seems to accept any email address just fine.

Enter “PushChat” for Common Name. You can type anything you want here, but choose something descriptive. This allows us to easily find the private key later.

Check Saved to disk and click Continue. Save the file as “PushChat.certSigningRequest”.

If you go to the Keys section of Keychain Access, you will see that a new private key has appeared in your keychain. Right click it and choose Export.

Exporting your private key with keychain access

Save the private key as PushChatKey.p12 and enter a passphrase.

For the convenience of this tutorial, I used the passphrase “pushchat” to protect the p12 file but you should really choose something that is less easy to guess. The private key needs to be a secret, remember? Do choose a passphrase that you can recall, or you won’t be able to use the private key later.

Making the App ID and SSL Certificate

Log in to the iOS Dev Center and “Select the Certificates, Identifiers and Profiles” from the right panel.

Certificates Identifies and Profiles

You will be presented with the following screen (Doesn’t the new dev center UI look sleek :))

Certificates, Identifiers and Profiles section

Since you’re making an iOS app select Certificates in the iOS Apps section.

Now, you are going to make a new App ID. Each push app needs its own unique ID because push notifications are sent to a specific application. (You cannot use a wildcard ID.)

Go to App IDs in the sidebar and click the + button.

Create App ID

Fill the following details:

  • App ID Description: PushChat
  • App Services Check the Push Notifications Checkbox
  • Explicit App ID: com.hollance.PushChat

It is probably best if you choose your own Bundle Identifier here – com.yoursite.PushChat – instead of using mine. You will need to set this same bundle ID in your Xcode project. After you’re done filling all the details press the Continue button. You will be asked to verify the details of the app id, if everything seems okay click Submit

Hurray! You have successfully registered a new App ID.

Registration Complete
In a few moments, you will generate the SSL certificate that your push server uses to make a secure connection to APNS. This certificate is linked with your App ID. Your server can only send push notifications to that particular app, not to any other apps.

After you have made the App ID, it shows up like this in the list:

List of App Ids

Select the PushChat app ID from the list. This will open up an accordion as shown below:

Push App accordion

Notice in the “Push Notification” row, there are two orange lights that say “Configurable” in the Development and Distribution column. This means your App ID can be used with push, but you still need to set this up. Click on the Setting button to configure these settings.

App ID Settings

Scroll down to the Push Notifications section and select the Create Certificate button in theDevelopment SSL Certificate section.

Create Development Certificate

The “Add iOS Certificate” wizard comes up:

Add iOS Certificate

The first thing it asks you is to generate a Certificate Signing Request. You already did that, so clickContinue. In the next step you upload the CSR. Choose the CSR file that you generated earlier and clickGenerate.

Generate Certificate

It takes a few seconds to generate the SSL certificate. Click Continue when it’s done.

Now click Download to get the certificate – it is named “aps_development.cer”.

Click Download

As you can see, you have a valid certificate and push is now available for development. You can download the certificate again here if necessary. The development certificate is only valid for 3 months.

When you are ready to release your app, repeat this process for the production certificate. The steps are the same.

Note: The production certificate remains valid for a year, but you want to renew it before the year is over to ensure there is no downtime for your app.

You don’t have to add the certificate to your Keychain, although you could if you wanted to by double-clicking the downloaded aps_development.cer file. If you do, you’ll see that it is now associated with the private key.

Making a PEM File

So now you have three files:

  • The CSR
  • The private key as a p12 file (PushChatKey.p12)
  • The SSL certificate, aps_development.cer

Store these three files in a safe place. You could throw away the CSR but in my opinion it is easier to keep it. When your certificate expires, you can use the same CSR to generate a new one. If you were to generate a new CSR, you would also get a new private key. By re-using the CSR you can keep using your existing private key and only the .cer file will change.

You have to convert the certificate and private key into a format that is more usable. Because the push part of our server will be written in PHP, you will combine the certificate and the private key into a single file that uses the PEM format.

The specifics of what PEM is doesn’t really matter (in fact, I have no idea) but it makes it easier for PHP to use the certificate. If you write your push server in another language, these following steps may not apply to you.

You’re going to use the command-line OpenSSL tools for this. Open a Terminal and execute the following steps.

Go to the folder where you downloaded the files, in my case the Desktop:

$ cd ~/Desktop/

Convert the .cer file into a .pem file:

$ openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem

Convert the private key’s .p12 file into a .pem file:

$ openssl pkcs12 -nocerts -out PushChatKey.pem -in PushChatKey.p12
Enter Import Password: 
MAC verified OK
Enter PEM pass phrase: 
Verifying - Enter PEM pass phrase: 

You first need to enter the passphrase for the .p12 file so that openssl can read it. Then you need to enter a new passphrase that will be used to encrypt the PEM file. Again for this tutorial I used “pushchat” as the PEM passphrase. You should choose something more secure.

Note: if you don’t enter a PEM passphrase, openssl will not give an error message but the generated .pem file will not have the private key in it.

Finally, combine the certificate and key into a single .pem file:

$ cat PushChatCert.pem PushChatKey.pem > ck.pem

At this point it’s a good idea to test whether the certificate works. Execute the following command:

$ telnet gateway.sandbox.push.apple.com 2195
Trying 17.172.232.226...
Connected to gateway.sandbox.push-apple.com.akadns.net.
Escape character is '^]'.

This tries to make a regular, unencrypted, connection to the APNS server. If you see the above response, then your Mac can reach APNS. Press Ctrl+C to close the connection. If you get an error message, then make sure your firewall allows outgoing connections on port 2195.

Let’s try connecting again, this time using our SSL certificate and private key to set up a secure connection:

$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 
    -cert PushChatCert.pem -key PushChatKey.pem
Enter pass phrase for PushChatKey.pem: 

You should see a whole bunch of output, which is openssl letting you know what is going on under the hood.

If the connection is successful, you should be able to type a few characters. When you press enter, the server should disconnect. If there was a problem establishing the connection, openssl will give you an error message but you may have to scroll up through the output to find it.

Note: There are two different APNS servers: the “sandbox” server that you can use for testing, and the live server that you use in production mode. Above, we used the sandbox server because our certificate is intended for development, not production use.

Making the Provisioning Profile

You’re not yet done with the iOS Dev Center. Click the Provisioning Profiles button in the sidebar and click the + button.

Create new provisioning profile

This will open up the iOS provisioning profile wizard.

Step 1: Select Type

Select the “iOS App development” option button in the first step of the wizard and press Continue.

Select Development Option

Step 2: Configure

Select the PushChat app id that you created in the previous section. This will ensure that this provisioning profile is explicitly tied to the PushChat app.

Select PushChat App ID

Step 3: Generate

In this step you select the certificates you want to include in this provisioning profile. This step should be quite routine by now.

Select Certificate for Provisioning profile

Step 4: Select devices

Select the devices you want to include in this provisioning profile. Since you’re creating the development profile you would typically select the devices you use for development here.

Select devices for development provisioning profile

Step 5: Name this profile

Set the provisioning profile name as “PushChat Development” as shown below.

Name provisioning profile

You’re almost done! Finally press the Download button, this will download the newly created Development provisioning profile.

Add the provisioning profile to Xcode by double-clicking it or dragging it onto the Xcode icon.

If you’re ready to release your app to the public, you will have to repeat this process to make an Ad Hoc or App Store distribution profile.

A Very Basic App

So far things haven’t been really exciting, but those preliminaries are necessary. I wanted to show you in detail how to generate the certificate because it’s not something you do every day and push won’t work without it.

You’ve already established that your certificate is valid by connecting to the sandbox server. Let’s test if you can actually send some push notifications!

Fire up Xcode and choose File, New Project. In the assistant, pick Single View Application and continue to the next step.

Creating a View-Based Application with Xcode 4

I filled in these fields as follows:

  • Product Name: PushChat
  • Organization Name: Ray Wenderlich
  • Company Identifier: com.hollance
  • Device Family: iPhone

The Product Name and Company Identifier together form the Bundle ID. In my case that is “com.hollance.PushChat”. You should choose a Product Name and Company Identifier that correspond to the App ID that you made earlier in the Provisioning Portal (com.yourname.PushChat). Make sure that the “Use Storyboards” and “Use Automatic reference counting” checkboxes are checked.

Finish the assistant and open AppDelegate.m. Change the application:didFinishLaunchingWithOptions: method to look like this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	// Let the device know we want to receive push notifications
	[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
		(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
 
    return YES;
}

The new call to registerForRemoteNotificationTypes: tells the OS that this app wants to receive push notifications.

Build & Run the app. You need to do this on your device because the simulator does not support push notifications. Xcode should automatically have selected the new provisioning profile. If you get a code sign error, then make sure the proper profile is selected in the Code Signing build settings.

When the app starts and registers for push notifications, it shows a message to inform the user that this app wishes to send push notifications.

A Simple iPhone App Requesting Permission to Deliver Notifications

The app asks this only once. If the user picks “OK”, then we should be all set. However, if they choose “Don’t Allow” then our app will never receive push notifications. The user can reverse their decision in the phone’s Settings.

Viewing Push Notification Permissions in iPhone Settings

The name of your app will be added to the phone’s Settings, under Notifications. The user can enable or disable the notifications for your app here, including individual settings for badges, sounds, and alerts.

push_notifications_settings

Your app can find out which types of push notifications are enabled through:

UIRemoteNotificationType enabledTypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

There is one more thing you need to add in order to be able to receive push notifications. Add the following to AppDelegate.m:

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
	NSLog(@"My token is: %@", deviceToken);
}
 
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
	NSLog(@"Failed to get token, error: %@", error);
}

When your app registers for remote (push) notifications, it tries to obtain a “device token”. This is a 32-byte number that uniquely identifies your device. Think of the device token as the address that a push notification will be delivered to.

Run the app again and you should see something like this in Xcode’s console window:

My token is: 
<740f4707 bebcf74f 9b7c25d4 8e335894 5f6aa01d a5ddb387 462c7eaf 61bb78ad>

The token is an opaque binary data structure, stuffed into an NSData object. Apple doesn’t want you to mess around with its internals. For our purposes it is enough to know that it is currently 32 bytes long. As you can see above, the token can be represented by 64 hexadecimal characters. You will be using it in that format, although you still strip off the brackets and leave out the spaces.

If you run the app in the simulator, the application:didFailToRegisterForRemoteNotificationsWithError: method will be called as push notifications are not supported in the simulator.

That’s it for the app. There is one more thing to do and then you can finally see some push notifications in action!

Sending Your First Push Notification

As I’ve mentioned a few times before, you need to set up a server that sends the push notifications to your app. For this first test, you’re not going to set up a server just yet. Instead, I’ll give you a very simple PHP script that sets up a connection to APNS and sends a push notification to a device token that you specify. You can run this straight from your Mac.

Download the SimplePush code and unzip it. You need to make some changes to simplepush.php.

// Put your device token here (without spaces):
$deviceToken = '0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78';
 
// Put your private key's passphrase here:
$passphrase = 'pushchat';
 
// Put your alert message here:
$message = 'My first push notification!';

You should copy the device token from the app into the $deviceToken variable. Be sure to leave out the spaces and brackets; it should just be 64 hexadecimal characters. Put your private key’s passphrase into $passphrase, and the text you wish to send in $message.

Copy your ck.pem file into the SimplePush folder. Remember, the ck.pem file contains both your certificate and the private key.

Then open a Terminal and type:

$ php simplepush.php

If all goes well, the script should say:

Connected to APNS
Message successfully delivered

And within a few seconds you should receive your first push notification:

Simple app receiving a Push Notification

Note that you won’t see anything when the app is open. The push message is delivered but you did not build anything in the app to handle it yet. Close the app and try again.

If the simplepush.php script exits with an error message, then check that you have made the PEM file correctly, and that you can connect to the sandbox server without problems (see above).

For now, it is not important what the script exactly does. I will explain more about this in the second part of the series when we build a true push server.

Troubleshooting

This section has a few tips to keep track of if you’re facing problems to get push notifications to work.

Some notifications received but not all: If you’re sending multiple push notifications simultaneously and you receive only a few, fear not that is intended behaviour. APNS maintains a QoS (Quality of Service) queue for each device with a push app. The size of this queue is 1 so if you send multiple notifications then the last notification is overridden.

Problem connecting to Push Notification Service:

  1. One possibility here could be that there is a firewall blocking the ports used by APNs. Make sure youunblock these ports.
  2. Another possibility here could be that you’ve gotten the private key and CSR file wrong. While updating this tutorial I myself made this mistake and fixed it using the correct private key. Remember that each app id has a unique CSR and private key combination.
  3. Unable to get local issuer certificate. This error means that the certificate from the server could not be verified. To fix this you need to download the Entrust CA root certificate. This can be done from the Terminal using the command:
    curl -O https://www.entrust.net/downloads/binary/entrust_2048_ca.cer

    You then also need to add

    stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

    to the simplepush.php file after line 16.

Where To Go From Here?

At this point, you’ve successfully set up an app to receive push notifications, and delivered your first push notification through custom PHP code!

Next check out part 2 of the tutorial series, where I’ll cover how to make a simple direct messaging app called PushChat that uses push notifications to deliver the messages.

There you’ll learn how to make a complete server side API that delivers push notifications continuously in the background!

In the meantime, if you have any questions, comments, or suggestions, feel free to join in the forum discussion below!

เขียนเมื่อ หมวดหมู่ APP

รับ-ส่ง SMS ง่ายๆ ด้วย AirCard บน Raspberry Pi

ปัจจุบันมีโครงงานทางระบบสมองกลจำนวนมากที่ต้องการใช้ SMS ไม่ว่าจะเป็นเพื่อส่งข้อมูลจากเซ็นเซอร์ต่างๆ ไปเก็บที่ศูนย์กลาง  หรือเพื่อส่งข้อความแจ้งเตือนผู้ใช้ถึงเหตุการณ์ต่างๆ ที่ระบบตรวจสอบได้ ซึ่งเดิมการส่ง SMS นั้นต้องใช้อุปกรณ์เฉพาะที่ราคาแพง และต้องอาศัยความรู้เรื่องการต่อวงจร และเขียนโปรแกรมควบคุมพอสมควร แต่การรับ-ส่ง SMS โดยใช้ Raspberry Pi นั้นเป็นสิ่งที่ทำได้ง่ายมากๆ เพราะสามารถใช้ USB AirCard ที่มีจำหน่ายทั่วไป ซึ่งราคาคุ้มค่า และมีแนวโน้มถูกลงเรื่อยๆ ตามความนิยม ประกอบกับคำสั่งที่ใช้รับ-ส่ง SMS บน Linux นั้นง่ายมากๆ บทความนี้จะแนะนำและแสดงตัวอย่างการรับส่งข้อความอย่างง่าย เพื่อเป็นต้นแบบให้กับโครงงานที่ต้องการใช้ความสามารถนี้

อุปกรณ์ที่ต้องใช้

  1. Raspberry Pi (หรือคอมพิวเตอร์ที่ใช้ Linux และมี port USB ว่าง 1 พอร์ท)
  2. USB AirCard ที่เข้ากันได้กับระบบปฏิบัติการ Raspbian ของ Raspberry Pi (ดูรายชื่ออุปกรณ์ได้จากที่นี่) บทความนี้เลือกใช้ 3G AirCard ของ TrueMove-H ซึ่งภายในเป็นอุปกรณ์ของ Huawei รุ่น E303 ราคา 790 บาท (ซิมและโปรโมชันที่ใช้ต้องซื้อต่างหาก)
  3. โทรศัพท์มือถือเอาไว้ทดสอบการรับ-ส่งข้อความ

IMG_1921

การเตรียมระบบ

  • ติดตั้งโปรแกรม gammu และส่วนเสริมที่จำเป็น ให้เรียกใช้โปรแกรม Terminal แล้วพิมพ์คำสั่งต่อไปนี้ เครื่อง Raspberry Pi จะต้องเชื่อมต่อกับอินเทอร์เน็ต
sudo apt-get install gammu usb-modeswitch python-gammu
  • ลองเสียบ SIM ในโทรศัพท์มือถือทั่วไปและทดลองดูว่าสามารถรับส่งข้อความได้หรือไม่ เมื่อแน่ใจว่า SIM ใช้งานได้ ก็ให้ย้ายไปใส่ใน AirCard แล้วเสียบ AirCard เข้ากับช่อง USB ของ Raspberry Pi
  • ตรวจสอบว่า Raspberry Pi มองเห็น AirCard หรือไม่

ใช้คำสั่ง

lsusb

เนื่องจาก AirCard รุ่นที่ใช้ในตัวอย่างนี้จะทำตัวเป็น USB Drive ได้ด้วย ซึ่งบางครั้งจะทำให้ Raspberry Pi สับสน นึกว่าอุปกรณ์นี้ไม่ใช่ AirCard แต่เป็น USB Drive แทน ดังนั้นคำสั่ง lsusb จะให้ผลลัพท์ได้สองแบบ

เห็น AirCard (ถูกต้อง)

Bus 001 Device 010: ID 12d1:1506 Huawei Technologies Co., Ltd. E398 LTE/UMTS/GSM Modem/Networkcard

ไม่เห็น AirCard แต่เห็น USB Drive แทน (ผิด)

Bus 001 Device 010: ID 12d1:14d1 Huawei Technologies Co., Ltd.

แม้หากว่าลองแล้วได้ผลถูกต้อง แต่ก็เป็นไปได้ว่าบางครั้งเมื่อ reboot ระบบอาจกลับไปเห็นอุปกรณ์ที่ไม่ถูกต้องก็ได้ ดังนั้นถ้าให้แน่ใจจริงๆ ควรใช้โปรกรม usb-modeswitch เพื่อตั้งค่าอุปกรณ์ให้ถูกต้องตามขั้นตอนต่อไปนี้

  • ตั้งค่าโปรแกรม usb-modeswitch

โปรแกรมนี้ทำหน้าที่เปลี่ยนโหมดของอุปกรณ์ USB ที่มีหลากอุปกรณ์ในตัว และตั้งค่าเลือกอุปกรณ์ตัวที่เราต้องการใช้ การจะเลือกอุปกรณ์ จะต้องรู้รหัส Vendor ID กับ Product ID ซึ่งรหัสนี้จะต่างกันไปแล้วแต่ยี่ห้อและรุ่นของ AirCard ที่ใช้ ดังนั้นจะต้องไปค้นข้อมูลนี้จาก internet มาเองให้ตรงรุ่น แล้วนำค่านี้ไปเขียนต่อท้ายในไฟล์ /etc/usb_modeswitch.conf โดยใช้คำสั่งต่อไปนี้จาก Terminal

sudo nano /etc/usb_modeswitch.conf

เช่น AirCard Huawei E303 ที่ใช้ในบทความนี้จะมีค่ารหัสดังนี้ (หาพบจากการค้นหา “Huawei E303 USB vendor product Id” ใน Google)

DefaultVendor = 0x12d1
DefaultProduct = 0x1506

เมื่อเพิ่มสองบรรทัดนี้เข้าไปในไฟล์แล้วก็ให้ save ไฟล์ (กด Ctrl-X และ Y) แล้วลอง reboot เครื่อง และเรียก lsusb อีกครั้ง ซึ่งคราวนี้น่าจะเห็นอุปกรณ์ที่ถูกต้อง

  • ตรวจสอบชื่ออุปกรณ์ของ AirCard โดยใช้คำสั่ง
dmesg | grep ttyUSB*

สังเกตุบรรทัดที่มีคำว่า GSM modem และดูว่าอุปกรณ์ชื่ออะไร เช่น ttyUSB0, ttyUSB1, ฯลฯ จำชื่อนี้ไว้

  • ตั้งค่าโปรแกรม gammu

โปรแกรม gammu จะทำหน้าที่รับส่ง SMS ซึ่งจะต้องตั้งค่าให้โปรแกรมรู้จัก AirCard ที่ใช้ก่อน โดยพิมพ์คำสั่งต่อไปนี้

sudo gammu-config

ซึ่งจะแสดงหน้าต่างการตั้งค่าขึ้นมา ให้เราตั้งค่าดังนี้

Port: /dev/ttyUSB0 << แล้วแต่เสียบ port ไหน
 Connection: at19200 
 Model: ปล่อยว่างๆ 
 Synchronize time: yes 
 Log file: ปล่อยว่างๆ 
 Log format: nothing 
 Use locking: ปล่อยว่างๆ 
 Gammu localisation: ปล่อยว่างๆ

เมื่อเสร็จก็ให้ save แล้วออกจากโปรแกรม

 การส่ง SMS

เมื่อติดตั้งทุกอย่างเสร็จสิ้นแล้ว ต่อไปก็ให้ทดลองส่ง SMS โดยพิมพ์คำสั่งต่อไปนี้ใน Terminal โดยจะต้องเปลี่ยนหมายเลขโทรศัพท์ผู้รับให้ตรงกับโทรศัพท์ที่ใช้ทดสอบด้วย

 sudo gammu sendsms TEXT +66819876543 -textutf8 "Hello from Raspberry Pi"

คำสั่งนี้จะส่งข้อความ “Hello from Raspberry Pi” ไปยังหมายเลขโทรศัพท์ 081-987-6543 ซึ่งรูปแบบการเขียนเบอร์โทรศัพท์ที่เป็น +66819876543 นี้เป็นมาตรฐานนานาชาติ คือขึ้นต้นด้วย “+” ตามด้วยรหัสประเทศ (66 = ประเทศไทย) และตามด้วยเบอร์โทร โดยตัด 0 ตัวแรกทิ้งไป ต่อไปนี้เป็นตัวอย่างการส่ง SMS ข้างต้นโดยใช้ภาษา Python

1
2
3
4
5
import commands
commandString = 'sudo gammu sendsms TEXT +66819876543 -textutf8 "Hello from Raspberry Pi" '
print commands.getoutput(commandString)

การใช้ภาษา Python มีความยืนหยุ่นสูงกว่าเพราะทำให้เราสามารถสร้างข้อความที่รับค่าจากผู้ใช้ได้เช่น

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import commands
# Ask for your name
name = raw_input('What is your name? ')
# Ask for a phone number. Use the international format. +country-code phone-number,
# I.e. +66819876543
phoneNumber = raw_input('What is your phone number? ')
commandString = 'sudo gammu sendsms TEXT ' + phoneNumber + ' -textutf8 "Hello ' + name + '. This is Raspberry Pi"'
print 'Sending text "Hello ' + name + '. This is Raspberry Pi" to phone number ' + phoneNumber
# send the command to the AirCard
print commands.getoutput(commandString)

โปรแกรมข้างต้นจะถามชื่อ และหมายเลขโทรศัพท์จากผู้ใช้ แล้วทำการส่ง SMS ข้อความทักทายไปยังหมายเลขโทรศัพท์นั้น โปรแกรมนี้สามารถนำไปประยุกต์เพื่อใช้ส่งค่าอื่นๆ ได้เช่น ค่าที่อ่านจากเซ็นเซอร์ หรือเงื่อนไขที่ต้องการตรวจสอบ หรือกำหนดให้ส่งข้อความตามระยะเวลาที่กำหนด

การรับ SMS

ปกติหาก AirCard ทำงานอยู่เมื่อมี SMS ส่งเข้ามามันจะเก็บข้อความเหล่านั้นไว้ในหน่วยความจำภายใน SIM Card โดยอัตโนมัติ ซึ่งเราสามารถใช้ API ชื่อ python-gammu การอ่านและจัดการข้อความเหล่านี้ได้ โปรแกรมตัวอย่างต่อไปนี้จะทำการพิมพ์ข้อความ SMS ทั้งหมดที่มีใน SIM Card ออกมาพร้อมกับ หมายเลขโทรศัพท์ผู้ส่ง, วันเวลาที่ได้รับ, และสถานะ (อ่าน หรือ ยังไม่ได้อ่าน)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import gammu
def readAllSMS():
    sm = gammu.StateMachine()
    sm.ReadConfig()
    sm.Init()
    status = sm.GetSMSStatus()
    smsCount = status['SIMUsed']
    print "SMS count = " + str(smsCount)
    for i in range(0,smsCount):
         if i==0:
            sms = sm.GetNextSMS(Folder=0, Start=True)
         else:
            sms = sm.GetNextSMS(Folder=0, Location=i-1)
         print sms[0]['Number']     # Sender's phone number
         print sms[0]['DateTime']   # Receive date and time
         print sms[0]['State']      # message state (unread/read)
         print sms[0]['Text']       # SMS content
         print "=================================="
    print "Done"
readAllSMS()

โปรแกรมตัวอย่างถัดไปจะคอยตรวจสอบว่ามี SMS ใหม่เข้ามาหรือไม่ และทำงานตามคำสั่งที่ได้รับในข้อความนั้นๆ ซึ่งในที่นี้คือทำการเปิดปิดมอเตอร์ที่ต่อกับบอร์ด PiTopping

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import gammu
import time
from pibot import *
smsCount = 0
def executeCommand(command):
    if command=='on':
        talkTo('a')
        on()
    elif command == 'off':
        talkTo('a')
        off()
def checkSMS():
    global smsCount
    status = sm.GetSMSStatus()
    # check amount of SMS in the SIM card
    newSmsCount = status['SIMUsed']
    print "SMS count = " + str(newSmsCount)
    # if new SMS
    if (newSmsCount > 0) and (newSmsCount != smsCount) :
    smsCount = newSmsCount
       # read the SMS
       sms = sm.GetNextSMS(Folder=0, Location=smsCount-1)
       # only use 'unread' SMS
       if sms[0]['State'].lower() == 'unread':
           # copy the SMS content
           command = sms[0]['Text'].lower()
           print "New command: " + command
           # execute the SMS command
           executeCommand(command)   
    print "Done"
sm = gammu.StateMachine()
sm.ReadConfig()
sm.Init()
while True:
    print "Checking SMS"
    checkSMS()
    time.sleep(4)

การทำงานของโปรแกรมข้างต้นเป็นดังนี้

  • โปรแกรมจะคอยเรียกฟังก์ชัน checkSMS() ทุกๆ 4 วินาที
  • ในฟังก์ชัน checkSMS() จะทำงานดังนี้
    • จะคอยอ่านจำนวน SMS ที่มีอยู่ใน SIM และเอาไปเทียบกับจำนวนที่เก็บไว้ในตัวแปร smsCount หากมีค่าไม่เท่ากันก็แสดงว่ามีข้อความใหม่เข้ามา
    • เมื่อมีข้อความใหม่โปรแกรมก็จะตรวจสอบเพื่อความแน่ใจว่าสถานะของข้อความนั้นคือยังไม่ได้อ่าน (UnRead)  ถ้าเป็นจริงก็จะส่งข้อความนั้นให้ฟังก์ชัน executeCommand() นำไปประมวลผลต่อไป (ว่าควรเปิด หรือปิดมอเตอร์)

วิดีโอสาธิตการทำงานของโปรแกรม

คำแนะนำ

  • ในการรับ SMS ควรทำการลบข้อความที่ไม่ได้ใช้เป็นพักๆ เพื่อป้องกันไม่ให้หน่วยความจำของ SIM Card เต็ม ซึ่งอาจทำให้ไม่สามารถรับข้อความใหม่ๆ ได้ โดยคำสั่งที่ใช้ลบข้อความทั้งหมดใน SIM คือ
gammu deleteallsms 1

โดยจะเรียกใช้จาก Command Prompt หรือในภาษา Python ผ่านทาง คำสั่ง commands.getoutput() ก็ได้

  • จากการทดลองใช้งาน พบว่าบริษัทผู้ให้บริการมักมีการส่งข้อความ SMS โฆษณาประชาสัมพันธ์ต่างๆ เข้ามาบ่อยๆ ดังนั้นหากจะใช้การรับ SMS เพื่อสั่งงาน ควรตรวจสอบเนื้อหาให้แน่ใจเสมอว่าใช่คำสั่งที่ส่งมาจริงๆ หรือไม่

อ้างอิง

รายละเอียดและคำสั่งเพิ่มเติมเกี่ยวกับการควบคุมระบบ SMS สามารถศึกษาได้จาก

 สรุป

การรับและส่ง SMS นั้นทำได้ง่ายขึ้นมากเมื่อใช้ Raspberry Pi คู่กับ USB AirCard เทียบกับวิธีการเดิมของระบบสมองกลฝังตัวทั่วไป บทความนี้ได้แนะนำวิธีการเบื้องต้นในการใช้งาน SMS ซึ่งน่าจะครอบคลุมความต้องการพื้นฐานของโครงงานทั่วไปที่ต้องการใช้ความสามารถนี้

MYSQL Create databases

Pre-Flight Check
  • These instructions are intended for creating a MySQL database on Linux via the command line.
  • I’ll be working from a Liquid Web Core Managed CentOS 6.5 server, and I’ll be logged in as root.
Create a MySQL Database

First we’ll login to the MySQL server from the command line with the following command:

mysql -u root -p

In this case, I’ve specified the user root with the -u flag, and then used the -p flag so MySQL prompts for a password. Enter your current password to complete the login.

If you need to change your root (or any other) password in the database, then follow this tutorial on changing a password for MySQL via the command line.

You should now be at a MySQL prompt that looks very similar to this:

mysql>

To create a database with the name tutorial_database type the following command:

CREATE DATABASE tutorial_database;

If a database of the same name already exists, then a new database will not be created and you’ll receive this error:

ERROR 1007 (HY000): Can't create database 'tutorial_database'; database exists

To avoid seeing this error use the following command instead:

CREATE DATABASE IF NOT EXISTS tutorial_database;

The above command will only create the database tutorial_database if a database of that name does not already exist.

View All MySQL Databases

To view the database you’ve created simply issue the following command:

SHOW DATABASES;

Your result should be similar to this:

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| test               |
| tutorial_database  |
+--------------------+
4 rows in set (0.00 sec)

FreeBSD 10 FAMP

FAMP – Installing Apache2.4, MySQL, PHP on FreeBSD 10

Here is a procedure to install a FAMP(FreeBSD with Apache, MySQL and PHP) server. The following setup runs Apache 2.4, MySQL 5.6, and PHP 5.5 on FreeBSD 10. If any version of the packages needs to be changed, replace the versions in the commands accordingly.

Pre-Installation Tasks

Before installation of the components, Download the compressed snapshot of the ports collection, using the following command

# portsnap fetch

Now extract the snapshot into /usr/ports using the following command

# portsnap extract

Apache 2.4 – Installation and Configuration

# cd /usr/ports/www/apache24
# make install

(While running “make install” the installer asks to check the boxes to install various libraries and support packages. Check the appropriate boxes as per requirements.

# make clean

Edit the apache configuration file i.e. /usr/local/etc/apache24/httpd.conf and make the following changes

ServerRoot "/usr/local"
ServerAdmin you@your.address
ServerName www.example.com:80
DocumentRoot "/usr/local/www/apache24/data"
Listen :80

Edit the /etc/hosts file and add the following line:

<ip-address>                  <hostname>.<domain>

eg:

192.168.1.1               hostname.example.org

Create a file named /boot/loader.conf or edit it if it is already present and add the following line:

accf_http_load="YES"

Add the following line to /etc/rc.conf

 apache24_enable="YES"

Test the apache server installation using the following command:

# /usr/local/sbin/apachectl start

MySQL – Installation and Configuration

# cd /usr/ports/databases/mysql56-server/
# make install
# make clean

Start MySQL

 # /usr/local/etc/rc.d/mysql-server onestart

Add the following line to the file /etc/rc.conf

 mysql_enable="YES"

Set password for my sql using the following command

# rehash
# mysqladmin -uroot password ''

Configuring mysql

Use the following command

 # cp /usr/local/share/mysql/my-default.cnf /etc/my.cnf

Restart mysql using the following commands

# /usr/local/etc/rc.d/mysql-server restart

PHP – Installation and Configuration

Use the following commands to install PHP5.5 and other supporting packages

# cd /usr/ports/lang/php55
# make install
# make clean

Check the option ‘Build Apache Module’ as shown in the image and continue

PHP_apache module

Edit /usr/local/etc/apache24/httpd.conf file and add the following lines under /AddType

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

And add the following line under LoadModule section

LoadModule php5_module        libexec/apache24/libphp5.so

Modify the line ‘DirectoryIndex index.html’ to the following

 DirectoryIndex index.php index.html

Now restart the apache server by using the following command

# /usr/local/sbin/apachectl restart

Setup 2 NIC BSD

/etc/rc.conf

ifconfig_bge0=”inet 192.168.10.100 netmask 255.255.255.0″

defaultrouter=”192.168.10.1″
ifconfig_bge1=”inet 192.168.20.100 netmask 255.255.255.0″