So I’ve been starting to deploy nginx on more systems, and working with php5-fpm and have had some great success. However a few issues have come to light, and it was hard to find information about these issues online. Lots of Google digging later I’ve found quite a bit about nginx and PHP5-FPM.

Configuring nginx and PHP5-FPM Chroot

The chroot function of PHP5-FPM is a great feature, however it’s rather hard to troubleshoot for instance when a blank page is displayed. This is usually related to the fact that nginx is not passing the right path and file name to PHP5-FPM. There are two important pieces of information both nginx and PHP5-FPM will need.

I’ve pasted below a copy of my nginx location code for PHP files:

location ~ \.php {
try_files $uri =404;
keepalive_timeout 0;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME public_html/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include /etc/nginx/fastcgi_params;

The “SCRIPT_FILENAME” and “PATH_INFO” variables are defined within the nginx configuration for this particular domain. This is required, as this will be passed on to the PHP5-FPM daemon that will be running and processing the PHP code.

Here’s the PHP5-FPM pool for the above domain.

listen =
listen.allowed_clients =
user = doc
group = doc
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 2
chroot = /home/doc
php_admin_value[session.save_path] = tmp

The “chroot” variable specifies the root directory the processes and children will run from, therefore they will not be able to go lower than this directory.

Looking at both pieces of code, you can see how its imperative to ensure both the “SCRIPT_FILENAME” and “chroot”  variables are correctly set to ensure that paths are correctly specified. Failure to do so will result in a blank page and no real errors messages within any of the logs for nginx or PHP5-FPM.

PHP5-FPM Chroot and MySQL

If you’re using PHP5-FPM chroot, then you might run into some error messages that will make no sense at all. I ran into the follow error that was being displayed on a MediaWiki installation.

(Can't contact the database server: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) (localhost))

Upon further investigation and some Google! I’ve found this following thread that talks about how PHP is compiled and

How to flash Ubiquiti Bullet M2 with OpenWRT

This article will guide you through the steps of flashing your newly purchased Ubiquiti Bullet M2 with OpenWRT. Now I am actually flashing my Bullet M2 for a second time, I set the transmit power too high and it won’t boot up. The instructions below are pretty much from a re-flashing perspective.

Finding the right OpenWRT Firmware

You don’t need the AirOS firmware as you will be using the OpenWRT firmware. There isn’t any official packages from the OpenWRT for the Bullet M2. You can download nightly builds from their trunk. Here is a location that seems to be building images for the Bullet M2:


The following forum posts shows proof that the firmware boots on the device.


Getting into Firmware Recovery Mode

This part is rather easy, you can follow the instructions on Ubiquiti Networks website. Here’s the simple rundown, and you can complete this using Windows/Mac/Linux.

1. You need a TFTP client, you can use a GUI or you can used the built in OSX or Linux utility.

2. Set you network card to the following network IP Address:, Subnet Mask :

3. Plug the Bullet M2 into your network card.

4. Begin by depressing the reset button. Keep holding, then power the unit on. Wait 8 seconds then release the button (if you want to reset the unit to factory defaults, wait at least 15 seconds). Signal LEDs will be lit indicating that the device is ready for recovery

5. Make sure that AirOS device responds to pings, ping if it does not, go back to the first step.

6. Upload firmware image file .bin to, using a TFTP client software (binary mode).

7. Signal LEDs will keep blinking one by one in 4 different colors during firmware upgrade. Wait for about 7-10 minutes (devices and firmware depending) – do not power off the device during the procedure!

You’re done!

Setting up OpenWRT on the Bullet M2

When you flash OpenWRT on the Bullet M2, it will be available on the IP Address using telnet without a password. First lets secure the device and type “passwd” and set a root password.

[email protected]:/# passwd
Changing password for root
New password:
Bad password: too weak
Retype password:
Password for root changed by root
[email protected]:/#

Secured! Telnet will be disabled and SSH will now be enabled so remember you can only SSH in using “root” past this point.

There isn’t much you can do at this point, since you’ve flashed the micro version of the firmware. There is no web interface (Luci) or anything of real use, so we need to install some packages.

So we will need to give the Bullet M2 some sort of internet access, you can also just upload and install packages via SCP but I don’t really like that so much. The best way is  the following method.

With the Bullet connected to ethernet port, SSH/Telnet in and run “udhcpc -i br-lan”. You will get disconnected, but if you do a “tcpdump -i en0” you should see DHCP requests coming from the Bullet, which will continue until it gets a DHCP lease or until you power the device off. Now all you need to do is plug the Bullet into your router and viola! It will grab an IP, you just need to login to your router and check the DHCP leases and you should see the Mac for the Bullet with an IP.

You should now be able to SSH into the Bullet with its new IP Address it got from your router’s DHCP server!

Now lets install some packages, but we will first update opkg!

[email protected]:~# opkg update
Downloading http://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/Packages.gz.
Inflating http://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/Packages.gz.
Updated list of available packages in /var/opkg-lists/snapshots.

Lets install Luci so we can access the OpenWRT Web Interface:

Adventures in cPanel and mod_fcgid/Apache mpm_worker

I’ve started using cPanel on my main box, as well as some VPS accounts for a couple of customers. I never really enjoyed using a “Control Panel”, but ever since moving to cPanel I’ve actually enjoyed the experience. Previous to cPanel I was mostly using scripts I’ve coded in perl, which worked well. But there was no way to provide the users with control without writing lots of lines of code. Why re-invent the wheel?

Before cPAnel I use to run Apache2/mod_fcgid/mpm_worker with an entirely custom configuration. cPanel comes with something called EasyApache, which allows you to go step by step through how Apache and PHP will be configured and setup. It will download the required source and then build, all automatically unless something breaks which is rare.

EasyApache supports mpm_worker and mod_fcgid, which builds and works for the most part. The only exception is the fact that are issues with mod_fcgid/2.3.5 that seems to leave left over PHP processes. These processes sit idle while eating up memory, eventually if you have enough of them your machine will run into “OOM\Out Of Memory Errors”. Which is ugly. I have a post up on cPanel’s forum:


There has been a suggestion to upgrade to mod_fcgid/2.3.6 which I’ve done and still seem to have

How to Combat Conficker on a Large Network

The following is information and tools for dealing with a Conficker Outbreak on a Large Enterprise Network with lots of clients.

How to unlock all of your Active Directory Accounts with a script.


Set objRootDSE = GetObject(“LDAP://rootDSE”)
strDNSDomain = objRootDSE.Get(“defaultNamingContext”)

Set objCommand = CreateObject(“ADODB.Command”)
Set objConnection = CreateObject(“ADODB.Connection”)
objConnection.Provider = “ADsDSOObject”
objConnection.Open “Active Directory Provider”
objCommand.ActiveConnection = objConnection

StartNode = strDNSDomain
SearchScope = “subtree”

‘Filterstring = “(&(objectCategory=Person)(objectClass=User)” _
‘& “(userAccountControl:1.2.840.113556.1.4.803:=16))” ‘find locked out accounts (bitwise)

Filterstring = “(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))”   ‘not sure which is better

Attributes = “adspath”

LDAPQuery = “<LDAP://” & StartNode & “>;” & FilterString & “;” _
& Attributes & “;” & SearchScope

objCommand.CommandText = LDAPQuery
objCommand.Properties(“Page Size”) = 100
objCommand.Properties(“Timeout”) = 30
objCommand.Properties(“Cache Results”) = False
Set objRecordSet = objCommand.Execute

If NOT objRecordSet.eof Then
While Not objRecordset.EOF
Set objuser = GetObject(objRecordSet.Fields(“AdsPath”).Value)
objUser.IsAccountLocked = False
End If

Set objRootDSE = Nothing
Set objConnection = Nothing
Set objRecordSet = Nothing

msgbox “All users are now unlocked!”