Monthly Archives: October 2015

.htaccess: php_flag not allowed here

Many websites suggest that you add “AllowOverride All” to your apache configuration to allow the use of php_flag in .htaccess files. But in fact you only have to add “Options”, like this:

Directory "/var/www/example"
<Directory "/var/www/example">
AllowOverride  FileInfo Limit Options
...
</Directory>

Check this link to see if a specific php value can be set in an .htaccess file:
http://php.net/manual/de/ini.list.php

MySQL error “Incorrect key file for table”

Usually this error can be corrected by running “myisamchk -r <tablename.MYI>” on the myisam table in question. But this time it didn’t resolve the error.

Let’s take a close look at the error message:

Incorrect key file for table '/tmp/#sql_5b1f_0.MYI'; try to repair it [126]

The location of the myisam file is really strange. It is in the /tmp folder and not in the database directory. Also the name of the table looks like it is not part of the original database.

If this happens mysql is trying to create a temporary table in the tmp folder to resolve a very large query. It is using temporary tables to store intermediate results for large queries. But if there is not enough space in the tmp folder to create the corresponding key files, MySQL throws the above error message. Which is – in this case – a little bit misleading.

To resolve the problem I just had to enlarge my /tmp partition. Originally it was just 350 MB in size, which is really a bad idea for a database server. So I gave it another 800 MB, and the error message disappeared.

Automatically run bacula’s copy / migrate jobs

Recently I had some trouble to get bacula’s copy jobs running. Here are my experiences.

By the way: There are no differences between copy and migrate jobs in terms of configuration (except for the job type in the job resource of bacula-dir.conf), so you can use this little tutorial for both of them.

First of all you need to realize that bacula’s copy jobs do not run automatically, no matter how you run or configure them. Even though it would be a nice idea to have a copy job run automatically after the corresponding backup job has finished (e.g. to transfer the backed up files from disk to tape), bacula does not support this feature yet. You have to run the copy job yourself after the corresponding backup job has finished. But how do you do this?

My first approach was to start the copy job one minute after the original backup job has started. Consider the following scenario in your bacula-dir.conf:

Job {
  Name = "Backup1"
  Type = Backup
  Schedule = "DailyCycle"
  ...
}
Job {
  Name = "Copy1"
  Type = Copy
  Schedule = "DailyCycleCopy"
  Priority 100
  ...
}
Schedule {
  Name = "DailyCycle"
  Run = Full mon-sun at 20:00
}
Schedule {
  Name = "DailyCycleCopy"
  Run = Full  mon-sun at 20:01
}

In this example, the copy job runs one minute after the corresponding backup job (assuming that all other settings e.g. for the pool and storage resources are done right). But it WON’T work. Yes, the copy job starts one minute after the backup job, and because of its lower priority (100 is a lower priority than the default 10) it waits until the backup job has finished and does not run in parallel. But the copy job cannot find the backup job. It might find the backup job from the day before, or it might terminate immediately without doing anything. Maybe it has to do with the database update of the backup job that will take too long. So the copy job runs before the backup job has updated the database. In my case I was using a local MySQL database for the bacula server installation.

Next I was stumbling across the “Run = …” keyword in the job resource. It is supposed to run another job right before its own job. I was doing something like this:

Job {
  Name = "Backup1"
  Type = Backup
  ...
}
Job {
  Name = "Copy1"
  Type = Copy
  Run = "Backup1"
  Schedule = "DailyCycle"
  Priority 100
  ...
  }

Again because of its lower priority, the copy job should first start the backup job, wait until the backup job has finished and then start itself. I don’t know how the Run directive should work. But for me it was not working at all. The backup job did not start at all, and the copy job terminated immediately without doing anything.

Last I was following some advice from the internet and tried using the RunScript directive:

Job {
  Name = "Backup1"
  Type = Backup
  Schedule = "DailyCycle"
RunScript {
Command = "echo 'run job=Copy1 yes' | bconsole'"
RunsWhen = After
RunsOnFailure = No
RunsOnSuccess = Yes
RunsOnClient = No
}
  ...
}

Job {
  Name = "Copy1"
  Type = Copy
  ...
  }

First it did not work either. This is because of the pipe symbol “|” in the Command directive. I had to change it to point to an external shell script wrapper without using any special characters:

  ...
RunScript {
Command = "/etc/bacula/startJob.sh Copy1"
...

/etc/bacula/startJob.sh:

#!/bin/bash
echo "run job=$1 yes " | bconsole

Here we go. Finally copy jobs were working. The backup job was starting at the scheduled time. After finishing successfully it runs the external shell script which in turn starts the copy job. There is enough time for the backup job to finish, so the copy job recognizes the just finished backup job and transfers its data to tape.

I was using bacula version 5.2.x. Maybe this behaviour will change in future bacula versions.

 

Secure download for Debian

The basic idea  for downloading the Debian installation image in a secure way is this:

  1. Download the Debian public key from keyring.debian.org.
  2. Using that key you verify the signature of checksum file of the ISO image.
  3. With the checksum file you check the downloaded iso image to see if it is the original file and has not been changed or tampered with.

Here are the steps to take:

0. Most important: Make sure to follow this procedure on a computer that is secure and that you fully trust. Otherwise all of the following steps are pretty much useless.

1. Download the Debian public key:
gpg –keyserver hkp://keyring.debian.org –recv-keys 6294BE9B

Make sure the key has really been imported in your public gpg keyring:
gpg –fingerprint -k

The “–fingerprint” option shows the fingerprint of the just imported key. Compare it with the fingerprint on the official Debian website: https://www.debian.org/CD/verify
Make sure to double check the SSL certificate of that website in your browser.

2. Download the checksum file for the ISO image and the corresponding signature file:
wget http://cdimage.debian.org/…/SHA512SUMS
wget http://cdimage.debian.org/…/SHA512SUMS.sign

Check the validity of the checksum file:
gpg –verify SHA512SUMS.sign

3. Check the validity of the downloaded ISO image file:
sha512sum -c SHA512SUMS

Browser blank page / white page with php script (WordPress, etc.)

I recently had a completely white / blank browser page when I tried to reset my WordPress password. It was from a local WordPress installation on my Debian 8 Jessie server. I was resetting my password for the admin login. It turned out that there was a problem with my php.ini settings. I had to add the following paths to the open_basedir variable:

open_basedir = /usr/share/php:/usr/share/php5

When resetting the WordPress password, WordPress includes some php files to send a reset email in wp-includes/pluggable.php:

require_once ABSPATH . WPINC . '/class-phpmailer.php';
require_once ABSPATH . WPINC . '/class-smtp.php';

The problem is that with the standard wordpress package on Debian 8 Jessie, class-phpmailer.php and class-smtp.php are symbolic links to /usr/share/php/… . If this path is not included in open_basedir, the php script just terminates without sending any error messages. I couldn’t find anything in the apache logs either. The browser showed a blank page.

This might also be a problem with other php web applications. So if you experience a similar situation (no output of php script, blank page) you might want to check the open_basedir variable in you php.ini and make sure that all required / included php files and symbolic links are part of it.

If you have any ideas how to find out if a php script is trying to include a file outside of open_basedir, please leave a comment.