The Power of Automation Scripting with PHP

The problem faced by many system administrators is how to use a command-line scripting language, other than shell scripts, for automation.

PHP, now in its fifth major version, is one of the most popular web scripting languages. PHP is the new Perl. PHP has grown from a niche scripting language into a full-blown, enterprise-capable application framework. It’s supported by the Eclipse IDE and Microsoft’s Visual Studio. It has become the “go to” language for many of the world’s most popular online communities, applications, and cloud-based services. Think Drupal, Facebook, WordPress, Wikipedia, Flickr, and many others.

Although shell scripts are still valuable in scripting automated solutions, you can’t load modules for advanced features, such as database connectivity. In fact, you can easily combine PHP and shell scripts into a formidable application that’s virtually unbreakable and easy to maintain.

You might believe that PHP scripting is a Linux-only language, but PHP supports a variety of operating systems, including Windows. Windows has a few unsupported modules, but the list of supported ones is very long. One remedy for an all-Windows environment would be to install a small Linux virtual machine (VM) onto a Windows server. VirtualBox, QEMU, VMware Player, and VMware Workstation are all good hypervisors on which to run your Linux VM. Your particular needs, such as NAT’d ports or bridged networking will dictate one hypervisor over another.

For the purpose of this article, I’m assuming you have access to a Linux system as a standalone, physical system or as a virtual machine. You must have root access to install software on a Linux system, so that access is also assumed.

System Preparation

I only use Ubuntu for all Linux demonstrations, so everything, including installation of packages is Debian based. The following command will install PHP version 5.x, any dependencies, and key packages for using PHP 5.x at the command line.

$ sudo apt-get install php5 php5-cli php5-common

Once you’ve installed the necessary packages, you’re ready to write some scripts. If you’re familiar with PERL, shell scripting, or some other scripting language, you’ll find PHP’s syntax easy to learn and use.

Creating Scripts

Create a new empty file with your favorite command-line editor and begin with a simple PHP code block.

<?php

// This command lists all files in the root directory.
system('ls -C /');

?>

Save the file as list.php . The system() function runs an external command and returns the results to your screen (STDOUT). The -C switch for the ls command shortens the listing to streamline the output for more efficient online and print formatting.

To make the script work, run the list.php command:

$ php list.php

bin    etc     initrd.img      lost+found  proc     srv  var
boot   export  initrd.img.old  media       root     sys  vmlinuz
cdrom  home    lib             mnt         sbin     tmp  vmlinuz.old
dev    initrd  lib64           opt         selinux  usr

As you might suspect, you can run any system command or script in this same way. Try a few different commands and switches to test it for yourself.

Notice that you have to use the php command to parse your file and execute its contents. You can bypass this requirement with a simple shell command trick by adding the command to the file on the first line just as you would in a shell script.

For example, list.php now looks like:

#!/usr/bin/php
<?php

// This command lists all files in the root directory.
system('ls -C /');

?>

Save the file and add execute permission to it:

$ chmod 755 list.php

To execute your file, launch it as you would any shell script:

$ ./list.php

bin    etc     initrd.img      lost+found  proc     srv  var
boot   export  initrd.img.old  media       root     sys  vmlinuz
cdrom  home    lib             mnt         sbin     tmp  vmlinuz.old
dev    initrd  lib64           opt         selinux  usr

Either method is correct, but for automation, you’ll want to add in the “shebang” line, as shown, to every script, just as I do in every example in this article.

Issuing commands is interesting and useful, but you can perform real system administration tasks with command-line PHP, and for those repetitive tasks, you want to use a loop. For example, if you want to check which systems on your network have web servers running, you can write a simple script to check and report back to you. Create the following file and save it as portcheck.php .

#!/usr/bin/php -q
<?php
$systems = file("system_list.txt");
foreach($systems as $system)
{
$port = 80;

$fp = fsockopen($system,$port,$errno,$errstr,10);
if(!$fp)
{
echo "Port $port not available on $system";
}
else{
echo "Port $port is open on $system";
fclose($fp);
}
}
?>

Then, create a list of systems and save it to system_list.txt . Mine consists of five IP addresses:

192.168.1.70
192.168.1.78
192.168.1.85
192.168.1.240
192.168.1.250

Next, change the permissions to allow execution of the script and then execute the script:

$ ./portcheck.php

Port 80 is open on 192.168.1.70
Port 80 not available on 192.168.1.78
Port 80 is open on 192.168.1.85
Port 80 is open on 192.168.1.240
Port 80 is open on 192.168.1.250

Connecting to Remote Systems

A major PHP feature is built-in modules for almost everything imaginable. One of those features is SSH connectivity, which allows you to create scripts that interact with other systems in an automated fashion. However, the SSH capability isn’t built in to the downloadable version of PHP, you have to install a separate package: libssh2-php .

This module provides you with more than 25 SSH-related functions, giving your command-line PHP secure, scripted, host-to-host connectivity, including SSH, SCP, and SFTP functions that let you automate every type of SSH-related interaction with another host.

To install the package and any dependencies, issue the command:

$ sudo apt-get install libssh2-php

Now, it’s time to try a script using SSH. Please note that SSH is a little different from other protocols and requires special handling, called stream blocking, which is necessary to set up a temporary wait state to receive a response from the remote host.

The first step (Listing 1) is to set up your connect string (line 4). If you connect to multiple hosts using a loop, you could substitute a variable (e.g., $system ) for the static IP address or hostname. Next, you have to supply your authentication credentials (line 5), set the command string you want to send to the remote host (line 6), and start stream blocking (line 7), which executes the command and waits for the response. Now, write the output to a variable (lines 9-12), close the stream (line 14), and send the response to the screen (STDOUT; line 15).

Listing 1: SSH Script

01 #!/usr/bin/php
02 <?
03 
04 $ssh = ssh2_connect('192.168.1.85', 22);
05 ssh2_auth_password($ssh, 'khess', 'password');
06 $stream = ssh2_exec($ssh, '/sbin/ifconfig');
07 stream_set_blocking($stream, true);
08 
09 $response = '';
10 while($buffer = fread($stream, 4096)) {
11 $response .= $buffer;
12 }
13 
14 fclose($stream);
15 echo $response;
16 
17 ?>

Any spacing in the script is for readability and serves no other purpose.

Now you can save your script to ssh.php , add execute permissions to the script, and run it:

$ ./ssh.php

eth0      Link encap:Ethernet  HWaddr 08:00:27:b0:21:7e
          inet addr:192.168.1.85  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:feb0:217e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:495050 errors:0 dropped:0 overruns:0 frame:0
          TX packets:26284 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:215392635 (215.3 MB)  TX bytes:1759757 (1.7 MB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:88 errors:0 dropped:0 overruns:0 frame:0
          TX packets:88 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:7032 (7.0 KB)  TX bytes:7032 (7.0 KB)

If you’re running PHP scripts via Cron and don’t care to see the output, you can remove the stream blocking, response variable, and output from your script.

For example, to touch (create) a file on a remote system, use the following script:

#!/usr/bin/php

<?
$ssh = ssh2_connect('192.168.1.85', 22);

ssh2_auth_password($ssh, 'khess', 'password');

$stream = ssh2_exec($ssh, 'touch testing.txt');

?>

Save the script to writefile.php , add execute permissions, and run it. Your prompt will return to you in a few seconds with no output to your screen, but check the remote system to see the new file, testing.txt , in your home directory.

If you want to set up an automated script to copy a file between two systems, you can do so with the SCP or SFTP functions mentioned earlier. Usually, copying a file between systems requires no feedback or response, so your scripts will be very small and simple to write:

#!/usr/bin/php
<?php
$connection = ssh2_connect('shell.example.com', 22);

ssh2_auth_password($connection, 'username', 'password');

ssh2_scp_send($connection, '/home/khess/blah.txt', '/home/khess/blah.txt', 0644);
?>

This script will deliver your file with the umask you supply using the ssh2_scp_send() function.

The SFTP functions are a bit more elegant and flexible. Using them, you can create new directories, find the target of a symbolic link, resolve the real path of a path string, rename a remote file, remove a directory, retrieve file status information, create symlinks, and delete files, as well as, of course, SFTP files.

For example, to create the remote directory newdir:

#!/usr/bin/php
<?php
$connection = ssh2_connect('192.168.1.85', 22);
ssh2_auth_password($connection, 'khess', 'password');

$sftp = ssh2_sftp($connection);

ssh2_sftp_mkdir($sftp, '/home/khess/newdir');
?>

Web Programming and the Command Line

Most developers and observers know PHP because of its connection to web development, for which it’s widely used. PHP integrates very well with Apache, IIS, NGINX, and other popular web servers. Many of the Internet sites you connect to are programmed in PHP with a MySQL, PostgreSQL, or other database back end supporting them. PHP is an excellent web programming language.

For automation, the command-line (CLI) scripts that you’ve learned about here can help you create complete, intelligent applications that work in conjunction with your web applications. Much of what web pages do is on-demand interaction while scripts run unattended in the background, creating directories, moving files, deleting files, downloading files, extracting data from databases, inserting data into databases – typically on a Cron schedule.

When you create web applications, don’t adhere to the assumption that your web application must be 100 percent web . Your command-line scripts, once set up and debugged, require almost no maintenance or human interaction. PHP’s CLI works well as a web application partner. Explore it.

Summary

Automation is one method of replicating our work without incurring a lot of extra cost in a server environment. PHP and other scripting languages have distinct advantages over other types of automated solutions. Most scripting languages are free of charge, easy to learn, and require no exposure of TCP ports and no special privileges to run on a system.

Don’t be reluctant to mix and match your command-line scripts. Shell scripts, PHP, Perl, and others are all very powerful and have their own advantages and disadvantages. One solution might call for a Perl script, whereas others could be excellent PHP candidates. PHP is a flexible language that, like Perl, is mature and well-supported through commercial vendors and through worldwide developer communities.

Related content

comments powered by Disqus