Apache Backdoor Modul
Hello, world
Hier scheint ein brauchbares Tutorial für die erste Erfahrung zu liegen: http://www.penguinpowered.org/documentation/apache2_modules.html
Werde das jetzt mal durcharbeiten und meine Erfahrungen hier dokumentieren.
Webserver aufsetzen
Für dieses Beispiel habe ich einen Ubuntu Server frisch aufgesetzt. Bei abweichender Ausgangslage bitte entsprechend improvisieren.
Nach der Installation brauchen wir erstmal einen Apache2. Damit wir an das apxs-Kommando aus dem Tutorial kommen holen wir uns noch ein Zusatzpaket:
hund@surfer:~$ sudo apt-get install apache2 apache2-threaded-dev
Je nach verwendetem MPM scheint man statt apache2-threaded-dev auch apache2-prefork-dev verwenden zu können.
Die Standardkonfiguration vom Apachen sollte erstmal genügen --> Websites liegen in /var/www
Zuerst empfiehlt sich ein kurzer Blick in die Manpage.
hund@surfer:~$ man apxs2
Modul bauen
Zunächst erstelle ich eine Datei mod_hello.c in meinem home-Directory. Der Quellcode ist im Tutorial zu finden. Leider ist dieser fehlerhaft, hier die korrigierte und leicht gekürzte Fassung:
#include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "http_main.h" #include "http_protocol.h" #include "http_request.h" #include "util_script.h" #include "http_connection.h" /* This example just takes a pointer to the request record as its only * argument */ static int hello_handler(request_rec *r) { /* We decline to handle a request if hello-handler is not the value * of r->handler */ if (strcmp(r->handler, "hello-handler")) { return DECLINED; } /* The following line just prints a message to the errorlog */ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, r->server, "mod_hello: %s", "Before content is output"); /* We set the content type before doing anything else */ ap_set_content_type(r, "text/html"); /* If the request is for a header only, and not a request for * the whole content, then return OK now. We don't have to do * anything else. */ if (r->header_only) { return OK; } /* Now we just print the contents of the document using the * ap_rputs and ap_rprintf functions. More information about * the use of these can be found in http_protocol.h */ ap_rputs("<HTML>\n", r); ap_rputs("\t<HEAD>\n", r); ap_rputs("\t\t<TITLE>\n\t\t\tHello There\n\t\t</TITLE>\n", r); ap_rputs("\t</HEAD>\n\n", r); ap_rputs("<BODY BGCOLOR=\"#FFFFFF\>"\n" ,r); ap_rputs("<H1>Hello </H1>\n", r); ap_rputs("Hello world\n", r); ap_rprintf(r, "<br>A sample line generated by ap_rprintf<br>\n"); ap_rputs("</BODY></HTML>\n" ,r); /* We can either return OK or DECLINED at this point. If we return * OK, then no other modules will attempt to process this request */ return OK; } /* Each function our module provides to handle a particular hook is * specified here. See mod_example.c for more information about this * step. Suffice to say that we need to list all of our handlers in * here. */ static void x_register_hooks(apr_pool_t *p) { ap_hook_handler(hello_handler, NULL, NULL, APR_HOOK_MIDDLE); } /* Module definition for configuration. We list all callback routines * that we provide the static hooks into our module from the other parts * of the server. This list tells the server what function will handle a * particular type or stage of request. If we don't provide a function * to handle a particular stage / callback, use NULL as a placeholder as * illustrated below. */ module AP_MODULE_DECLARE_DATA hello_module = { STANDARD20_MODULE_STUFF, NULL, /* per-directory config creator */ NULL, /* directory config merger */ NULL, /* server config creator */ NULL, /* server config merger */ NULL, /* command table */ x_register_hooks, /* other request processing hooks */ };
Jetzt können wir das Modul erstellen:
hund@surfer:~$ sudo apxs2 -c -i -a mod_hello.c
Das kompiliert unseren Code zu einem Modul, kopiert die fertige .so-Datei an den richtigen Ort, aktualisiert die Apache2-Konfiguration und aktiviert das neue Modul. Für den späteren Produktiveinsatz werden diese Schritte manuell übernommen. Wenn alles gutgeht, sehen wir etwa das:
... chmod 644 /usr/lib/apache2/modules/mod_hello.so [preparing module `hello' in /etc/apache2/mods-available/hello.load] Enabling module hello. Run '/etc/init.d/apache2 restart' to activate new configuration!
Unser fertiges Modul liegt nun unter /usr/lib/apache2/modules/mod_hello.so. Was hat das Programm sonst noch gemacht?
Das Modul wurde aktiviert:
hund@surfer:~$ ls -l /etc/apache2/mods-enabled/ | grep hello lrwxrwxrwx 1 root root 28 2011-10-05 21:11 hello.load -> ../mods-available/hello.load
Und der Pfad wie oben beschrieben festgelegt:
hund@surfer:~$ cat /etc/apache2/mods-available/hello.load LoadModule hello_module /usr/lib/apache2/modules/mod_hello.so
Testlauf
Bevor wir unser Modul nun benutzen können, müssen wir noch den Handler aktiv schalten. Das können wir in einem beliebigen VirtualHost festlegen. Für dieses Beispiel habe ich /etc/apache2/sites-enabled/000-default verwendet.
Ich möchte, dass das neue Modul aufgerufen wird, wenn die Ressource /hello vom Apache erfragt wird. Dazu füge ich folgenden Knoten
<Location /hello> SetHandler hello-handler </Location>
...hinzu. Anschließend wird der Apache neu gestartet:
hund@surfer:~$ sudo /etc/init.d/apache2 restart
Wenn ich jetzt im Browser http://ip_vom_apache/hello abrufe, bekomme ich den generierten Text vom Modul ausgegeben. Greife ich auf andere Ressourcen zu, verhält sich Apache wie sonst auch. Nur bei der von uns festgelegten Ressource wird das Modul aktiv. Warum dieses Verhalten?
Im Quellcode des Moduls haben wir festgelegt, dass der Name des Handlers hello-handler ist.
/* We decline to handle a request if hello-handler is not the value * of r->handler */ if (strcmp(r->handler, "hello-handler")) { return DECLINED; }
In /etc/apache2/modules-enabled wird unser Modul geladen. Von nun an sind also alle Handler dieses Moduls verfügbar. Wenn wir nun in einem VHost diesen Handler verwenden möchten, müssen wir ihn nur noch beim Namen nennen. Das passiert im Location-Knoten von oben:
SetHandler hello-handler
Gratulation, wir haben jetzt ein funktionierendes Modul!
lama