Zone-Transfer von PowerDNS zu BIND9

DNS-Verwaltung ist immer so eine Sache. Ich baue meine Setups mittlerweile mit PowerDNS und BIND9 zusammen. PowerDNS dient als “versteckter” Master, der an sich nicht auf externe Anfragen antwortet. Die BIND9 Server beziehen ihre Zonen via Zonetransfer vom PowerDNS. Dazu kommt dann noch PowerAdmin. Somit hat man ein DNS-Setup mit Webinterface (und MySQL-Backend) und alle Vorteile in Sachen Geschwindigkeit von BIND9 bleiben erhalten.

Irgendwie muss die Slave-Config auf die BIND9-Slave Maschinen kommen. Hierzu ein kleines, simples PHP-Script.

#!/usr/bin/php
<?php
/**
 * Generiert eine BIND9 Slave Konfiguration aus
 * der PowerDNS-Master Datenbank.
 *
 * @author Simon Lauger <simon@lauger.name>
 * @date   11.06.2011
 */

$dsn    = 'mysql:dbname=pdns;host=127.0.0.1';
$user   = 'root';
$pass   = 'password';
$master = '127.0.0.1';

try {
    $dbh = new PDO($dsn, $user, $pass);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
    exit;
}

$result = $dbh->query('SELECT name FROM domains;');

foreach ($result as $row):
echo 'zone "'.$row['name'].'" {
   type slave;
   file "'.$row['name'].'.hosts";
   masters {
      '.$master.';
   };
};';
echo "\n";
endforeach;

?>

Diese Konfiguration wird komplett via Puppet auf unsere BIND9 Slaves verteilt.

class bind9 {
...
        file { "/etc/bind/named.conf.local":
                mode => 640,
                owner => root,
                group => bind,
                ensure => file,
                source => "puppet:///modules/bind9/named.conf.local",
        }
...
}

Um auch Konfigurationsänderungen zu berücksichtigen sollte zudem noch ein Reload des BIND9s via Cronjob eingerichtet werden.

MySQL Datenbank revisonieren

Ich bin derzeit dabei eine einfache Entwicklungsumgebung aufzubauen. Dabei habe ich nach einer vernünftigen Möglichkeit gesucht um Datenbankänderungen zu revisionieren, sprich alle Änderungen in der Struktur festzuhalten.

Niemand möchte alle SQL-Befehle für Strukturänderungen manuell dokumentieren. Ein kleiner Lebensretter ist hier das Perl Script “mysqldiff”. Das Tool kann mehrere Datenbanken miteinander vergleichen und gibt die Änderungen als SQL-Befehle zurück. Das bedeutet natürlich nicht, das man dadurch eine saubere Softwaredokumentation ersetzen kann.

wget http://adamspiers.org/computing/mysqldiff/MySQL-Diff-0.30.tar.gz
tar -xf MySQL-Diff-0.30.tar.gz
cd MySQL-Diff-0.30
perl ./Makefile.PL
make
make install

Zudem wird noch das Paket Class::MakeMethods::Template::Hash aus dem CPAN benötigt.

cpan Class::MakeMethods::Template::Hash

Gehen wir von der folgenden Situation aus: eine Datenbank “live” mit den Live-Daten sowie eine Datenbank “staging” mit Test-Daten. In der Tabelle “test_1″ in der Staging-Datenbank wurde das zusätzliche Feld “id” hinzugefügt.

CREATE DATABASE live;
CREATE TABLE live.test_1 (
  id int (11)
);

CREATE DATABASE staging;
CREATE TABLE staging.test_1 (
  id int (11),
  id2 int(11)
);

Nun können wir mittels mysqldiff die beiden Datenbanken miteinander vergleichen lassen. Zurück bekommen wir eine Liste mit SQL-Queries, um die Live-Datenbank auf den aktuellen Stand zu bringen.

root@dev01:~# mysqldiff -h localhost -u root -p gX8AmLuO8hWpqau3 live staging
## mysqldiff 0.30
##
## run on Tue Feb  7 22:48:32 2012
##
## ---   db: live (host=localhost user=root)
## +++   db: staging (host=localhost user=root)

ALTER TABLE `test_1` ADD COLUMN `id2` int(11) DEFAULT NULL;

Bestenfalls lässt man das ganze nun automatisiert in ein GIT/SVN Repository laufen. Zum überspielen der Änderungen bietet das Tool auch die Möglichkeit die Änderungen direkt (mittels –apply) auf die Live-Datenbank zu überspielen, jeweils mit einer Abfrage vor dem Absetzen jedes einzelnen SQL-Querys.

Configure Parameter für PHP 5.3.6

Etwas, an dem ich auch schon etwas länger sitze. Die optimale Konfiguration von PHP. Ich gebe zu, auch mit dem Hintergedanken zur Zend Certified Engineer Zertifizierung, die ich durchstarten werde, sobald ich wieder etwas Luft habe. Man lernt eben beim stöbern im Manual immer mal wieder was neues.

Sicherlich nicht perfekt, aber ich denke ein guter Anfang. Folgendes Setup läuft derzeit produktiv auf einem Ubuntu 8.04 LTS mit Lighttpd bei HostEurope (und warscheinlich in Zukunft auch auf einigen weiteren unserer Webserver):

'./configure' \
'--prefix=/usr' \
'--with-config-file-path=/etc/php5/cgi/' \
'--with-config-file-scan-dir=/etc/php5/cgi/conf.d/' \
'--mandir=/usr/share/man' \
'--disable-debug' \
'--with-regex=php' \
'--disable-rpath' \
'--disable-static' \
'--with-pic' \
'--with-layout=GNU' \
'--with-pear=/usr/share/php' \
'--enable-calendar' \
'--enable-sysvsem' \
'--enable-sysvshm' \
'--enable-sysvmsg' \
'--enable-bcmath=shared' \
'--with-bz2=shared' \
'--enable-ctype=shared' \
'--without-gdbm' \
'--with-iconv=shared' \
'--enable-exif=shared' \
'--enable-ftp=shared' \
'--with-gettext=shared' \
'--enable-mbstring=shared' \
'--enable-mbregex' \
'--with-pcre-regex=/usr' \
'--enable-shmop=shared' \
'--enable-sockets' \
'--enable-wddx=shared' \
'--with-libxml-dir=/usr' \
'--with-zlib' \
'--with-kerberos=shared,/usr' \
'--with-openssl=/usr' \
'--enable-soap=shared' \
'--enable-zip=shared' \
'--with-exec-dir=/usr/local/php/bin' \
'--without-mm' \
'--with-curl=shared,/usr' \
'--with-zlib-dir=/usr' \
'--with-gd=shared,/usr' \
'--with-gmp=shared,/usr' \
'--with-jpeg-dir=/usr' \
'--with-xpm-dir=/usr/X11R6' \
'--with-png-dir=/usr' \
'--with-freetype-dir=/usr' \
'--with-t1lib=shared,/usr' \
'--with-ldap=shared,/usr' \
'--with-ldap-sasl' \
'--with-mhash=shared' \
'--with-mysql=mysqlnd' \
'--with-mysqli=mysqlnd' \
'--with-pspell=shared,/usr' \
'--with-xsl=shared,/usr' \
'--with-snmp=shared,/usr' \
'--with-sqlite=shared,/usr' \
'--with-mssql=shared,/usr' \
'--with-tidy=shared,/usr' \
'--with-xmlrpc=shared' \
'--with-pgsql=shared,/usr' \
'--enable-gd-native-ttf' \
'--with-openssl-dir=/usr' \
'--enable-gd-jis-conv' \
'--enable-json' \
'--with-mcrypt=shared,/usr' \
'--enable-pcntl=shared' \
'--enable-pdo' \
'--with-pdo-mysql=mysqlnd' \
'--with-pdo-sqlite' \
'--with-pdo-pgsql=shared,/usr' \
'--enable-xmlreader=shared' \
'--with-tsrm-pthreads' \
'--with-recode=shared' \
'--disable-phar' \
'--disable-posix' \
'--disable-short-tags' \
'--enable-fast-install'

Und nun die Gedanken dahinter:

  • Grundsätzlich erstmal ein möglichst schlanker Core, indem unnötiges entfernt wird
  • CGI/FastCGI, da das System mit Lighttpd und mod_fastcgi betrieben wird
  • SQLite und MySQL/MySQLi werden als meistbenutzte Datenbankinterfaces fest implementiert
  • Ebenso die PDO-Datenbanktreiber für MySQL und SQLite
  • Für die MySQL/MySQLi-Funktionen sowie für PDO werden die neuen, nativen “mysqlnd” Treiber verwandt. Diese bieten eine verbesserte Performance und sind Ressourcenschonender als libmysql
  • Aus Sicherheitsgründen werden die Posix-Funktionen deaktiviert, die PCNTL-Funktionen als Shared gebaut (für CLI-Zwecke)
  • PHAR wird deaktiviert. Ist zwar eine schöne Idee, aber auf Produktiv-Systemen nicht zu gebrauchen
  • Zum Rest: Was ansonsten nicht auf allen Webseiten/virtuellen Hosts gebraucht wird und somit nicht direkt im Core einkompiliert sein muss, wird als Shared Module kompiliert

Gebaut wird das ganze für Debian/Ubuntu folgendermaßen:

cd /usr/src
wget http://de.php.net/distributions/php-5.3.6.tar.gz
tar -vxf php-5.3.6.tar.gz
cd php*
./configure...
make
checkinstall -D --install=no --fstrans=no --maintainer=cmon2k@sysadmin.local --reset-uids=yes --nodoc --pkgname=php5 --pkgversion=5.3.6 --pkgrelease=t4e-`date +%Y%m%d%H%M` --arch=amd64
dpkg -i php5_*.deb

Abschließend noch einige PEAR-Pakete, einige PECL-Extensions (APC usw.) nachinstallieren und man hat schon ein recht nettes PHP-Setup. Natürlich sollte man vor allen Arbeiten nicht vergessen die alten PHP-Pakete aus den Distributions-Repositorys zu deinstallieren.

Zend Server Community Edition

Der Zend Server CE ist komplettes Webserver Paket mit PHP 5.3.2, etwa vergleichbar mit dem Projekt XAMPP.

Der Vorteil liegt hier daran, dass bereits fast alle Komponenten von Zend mitgeliefert werden. So ist Out of the Box bereits Zend Data Cache, der Zend Debugger und Zend Optimizer+ installiert. Netterweise ist sogar das Zend Framework schon mit an Board.

Der Zend Server ist vorallem in Zusammenarbeit mit Zend Studio ein ziemlich mächtiges Entwicklerwerkzeug. Aber auch sonst bekommt man eine deutlich schönere Vorkonfiguration als bei XAMPP.

Der Zend Server arbeitet dabei mit dem Apache2 zusammen – unter Windows besteht auch die Möglichkeit ihn mit einem IIS laufen zu lassen.

Neben diesen Features liefert der Zend Server noch ein webbasiertes Konfigurationsinterface an. Dort lassen sich etwa PHP Erweiterungen per Klick aktivieren/deaktivieren, Direktiven in der php.ini setzen und die Zend Komponenten laden oder entladen.

Sehr schön ist dort auch der Logging Bereich, in dem man seine PHP Applikationen auf Errors und Warnings überwachen kann. Hier sind die Funktionen in der Community Edition gegenüber dem großen (kostenpflichtigen) Bruder recht beschränkt. Als Entwicklungsumgebung und für kleinere Projekte reicht die Community Edition aber durchaus aus.

Installation des Zend Servers CE
Für Debian werden bereits fertige Pakete von der Firma Zend selbst angeboten. Zur Installation führt man folgende hier Befehle aus:

wget http://repos.zend.com/deb/zend.key -O- | apt-key add -
echo deb http://repos.zend.com/zend-server/deb server non-free >> /etc/apt/sources.list
apt-get update
apt-get install zend-server-ce-php-5.3

Für Windows, Mac und andere Linux Distributionen kann man den Server hier herunterladen.

DHL-Tracking API mit PHP abrufen

Lange habe ich schon danach gesucht und endlich bin ich doch mal fündig geworden – die Tracking-API von DHL. Tatsächlich gibt es im Netz nahezu keine offizielle Dokumentation dieser mysteriösen API. Die public API dient zum Abrufen des Status eines Pakets, mit der privaten API können Firmen sich z. B. Paketaufkleber etc. ausdrucken lassen.

Die Public API reicht allerdings für die meisten Zwecke vollkommen, mit ihr kann man z. B. per Script die Sendung eines Pakets überwachen. Hier meine kleine, beispielhafte-Funktion:

function dhl_tracking($trackingnumber)
{
   $data  = '<?xml version="1.0" encoding="ISO-8859-1" ?>';
   $data .= '<data appname="nol-public" password="anfang" request="get-status-for-public-user" language-code="de">';
   $data .= '  <data piece-code="'.$trackingnumber.'"></data>';
   $data .= '</data>';

   // URL bauen und File hohlen
   $xml = simplexml_load_file(sprintf(
      'http://nolp.dhl.de/nextt-online-public/direct/nexttjlibpublicservlet?xml=%s', $data
   ));

   // FALSE, wenn Syntax oder HTTP Error
   if ($xml === false) return false;

   // Wandelt das SimpleXML Objekt in ein Array um
   foreach ($xml->data->data->attributes() as $key => $value) {
      $return[$key] = (string) $value;
   }
   return $return;
}

// Aufruf der Funktion
print_r(dhl_tracking($tracking_number));

Sollte die Funktion false zurück liefern gab es einen Problem mit dem Tomcat Server und der Anfrage (etwa falscher Syntax, fehlerhaftes XML). Wenn piece-status einen anderen Wert als 0 enthält liegt ein Problem mit dem Datensatz selbst vor (z. B. keine Daten vorhanden).

Den gesamten Artikel "DHL-Tracking API mit PHP abrufen" lesen »