GnuPG Encryption with PHP (on Ubuntu with Pecl)

Instructions for Getting this working on Ubuntu 12.04 and more modern systems than my previous post

Install the required system and pecl packages:

  # apt-get install gnupg  libgpgme11 libgpgme11-dev
  # pecl install gnupg
  # echo > /etc/php5/conf.d/gnupg.ini
  # apache2ctl restart

Generate a Private key

 # gpg --homedir /path/to/your/directory --gen-key

On a virtual machine, if that stalls for a while, you may have to generate some “randomness” somehow. Try one of these commands in a separate session, according to this bug report:

 # find / -type f | xargs grep blahblahblha
 # tcpdump -i any > /dev/null

At this point, you should have a working GPG key in the home directory you specified. You can list your secret keys with the command:

  # gpg --homedir /path/to/your/directory -K

You’ll then want to export the key with the command:

 # gpg --homedir /path/to/your/directory --export-secret-key --armour

You’ll want to copy that secret key to another machine. DON’T LOSE IT or you won’t be able to decrypt anything. Once you’ve got it safely stored somewhere, you want to delete it from your web server:

 #  gpg --homedir /path/to/your/directory --delete-secret-key

You can then make sure that the public key is still there. It is what you’ll need to encrypt messages:

 # gpg --homedir /path/to/your/directory -k

Finally, you’ll need the fingerprint for the key to refer to it within your PHP code.

 # gpg --homedir /path/to/your/directory --fingerprint 
pub   2048R/5BB54E26 2013-04-14 [expires: 2023-04-12]
      Key fingerprint = AAAA BBBB CCCC DDDD EEEE  FFFF 0000 1111 2222 3333
uid                  Your Name <>
sub   2048R/2EF4937A 2013-04-14 [expires: 2023-04-12]

You can then use the gnupg pecl functions to encrypt a messages:

$CONFIG['gnupg_home'] = '/var/www/.gnupg';
$CONFIG['gnupg_fingerprint'] = 'FA451EE9877270EF1CFA99CE048A613921CCC3D6';

$data = 'this is some confidential information';

$gpg = new gnupg();
$encrypted =  $this->gpg->encrypt($data);
echo "Encrypted text: \n$encrypted\n";

// Now you can store $encrypted somewhere.. perhaps in a MySQL text or blob field.

// Then use something like this to decrypt the data.
$passphrase = 'Your_secret_passphrase';
$gpg->adddecryptkey($CONFIG['gnugp_fingerprint'], $passphrase);
$decrypted = $gpg->decrypt($encrypted);

echo "Decrypted text: $decrypted";

Monit CPU Usage problem

I just recently fixed an issue I wanted my Monit monitoring process to restart a daemon who was segfaulting and causing 100% CPU usage according to top and most other system tools. I had seen configuration examples where Monit could detect that and restart the process, so I figured that adding a configuration like that below would fix it easily enough:

check process foo with pidfile /var/run/
  start program = "/etc/init.d/foo start" timeout 10 seconds
  stop program  = "/etc/init.d/foo stop"
  if cpu usage > 90% for 8 cycles then restart

After letting that run for a bunch of cycles the process remained running, and monit didn’t do anything to acknowledge it even in log files. (FYI, a “cycle” is defined in the Monitrc config file in the “set daemon” line and defaults to 120 seconds).

After some research, I finally came upon this post on the Monit mailing list where somebody describes that the CPU usage that Monit bases its numbers off is a percentage of the CPU available for all processors. My machine had 4 processors, so what was seeing as 100% CPU usage in top, monit would only see that as 25%.

I quickly changed my Monit config to check for CPU Usage > 22% as ween in the following. That now works perfectly, even acknowledging in the log each of the 8 times that the CPU was over the limit before restarting it:

check process foo with pidfile /var/run/
  start program = "/etc/init.d/foo start" timeout 10 seconds
  stop program  = "/etc/init.d/foo stop"
  if cpu usage > 22% for 8 cycles then restart

…. Now I need to solve the real problem and see why the latest Mongo PHP pecl module is segfaulting….