mod_tcpwrapper -- tcpwrapper support for Lighttpd
As mentioned in a previous post I have recently moved to a Debian squeeze box. This squeeze install is inside of an OpenVZ container so (as far as I know) I can't use tools like fail2ban to edit firewall rules. tcpwrappers works pretty good though as long as your services support it.
I'm already using the denyhosts package to ban people attempting to brute force the ssh service. so I figured I would set up lighty to use tcpwrappers as well.
When I did I found out that lighttpd does not currently have any tcp wrapper support. so I made this little lighttpd module to implement it.
Here is the diff between my code and the mod_skeleton.c file it is based off of
wschaub@deep13TP:/tmp/mod_tcpwrapper$ diff -u ../lighttpd-1.4.28/src/mod_skeleton.c mod_tcpwrapper.c
--- ../lighttpd-1.4.28/src/mod_skeleton.c 2010-08-17 05:04:38.000000000 -0400
+++ mod_tcpwrapper.c 2011-09-02 18:03:26.000000000 -0400
@@ -7,16 +7,15 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <tcpd.h>
/**
- * this is a skeleton for a lighttpd plugin
- *
- * just replaces every occurance of 'skeleton' by your plugin name
- *
- * e.g. in vim:
- *
- * :%s/skeleton/myhandler/
+ * mod_tcpwrapper by William Schaub <wschaub@steubentech.com>
+ * This module works like mod_access only it has no configuration parameters
+ * Instead it uses the TCP wrapper library to allow/deny access to the lighttpd
+ * daemon in /etc/hosts.allow and /etc/hosts.deny
*
+ * This module is under the same license as Lighttpd
*/
@@ -55,7 +54,7 @@
}
/* init the plugin data */
-INIT_FUNC(mod_skeleton_init) {
+INIT_FUNC(mod_tcpwrapper_init) {
plugin_data *p;
p = calloc(1, sizeof(*p));
@@ -66,7 +65,7 @@
}
/* detroy the plugin data */
-FREE_FUNC(mod_skeleton_free) {
+FREE_FUNC(mod_tcpwrapper_free) {
plugin_data *p = p_d;
UNUSED(srv);
@@ -97,12 +96,12 @@
/* handle plugin config and check values */
-SETDEFAULTS_FUNC(mod_skeleton_set_defaults) {
+SETDEFAULTS_FUNC(mod_tcpwrapper_set_defaults) {
plugin_data *p = p_d;
size_t i = 0;
config_values_t cv[] = {
- { "skeleton.array", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "tcpwrapper.array", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -130,7 +129,7 @@
#define PATCH(x) \
p->conf.x = s->x;
-static int mod_skeleton_patch_connection(server *srv, connection *con, plugin_data *p) {
+static int mod_tcpwrapper_patch_connection(server *srv, connection *con, plugin_data *p) {
size_t i, j;
plugin_config *s = p->config_storage[0];
@@ -148,7 +147,7 @@
for (j = 0; j < dc->value->used; j++) {
data_unset *du = dc->value->data[j];
- if (buffer_is_equal_string(du->key, CONST_STR_LEN("skeleton.array"))) {
+ if (buffer_is_equal_string(du->key, CONST_STR_LEN("tcpwrapper.array"))) {
PATCH(match);
}
}
@@ -158,10 +157,11 @@
}
#undef PATCH
-URIHANDLER_FUNC(mod_skeleton_uri_handler) {
+URIHANDLER_FUNC(mod_tcpwrapper_uri_handler) {
plugin_data *p = p_d;
int s_len;
size_t k, i;
+ struct request_info request;
UNUSED(srv);
@@ -169,38 +169,33 @@
if (con->uri.path->used == 0) return HANDLER_GO_ON;
- mod_skeleton_patch_connection(srv, con, p);
-
- s_len = con->uri.path->used - 1;
+ mod_tcpwrapper_patch_connection(srv, con, p);
- for (k = 0; k < p->conf.match->used; k++) {
- data_string *ds = (data_string *)p->conf.match->data[k];
- int ct_len = ds->value->used - 1;
+ /* init the request struct using the fd of our current connection */
+ request_init(&request, RQ_DAEMON,"lighttpd", RQ_FILE,con->fd, 0);
- if (ct_len > s_len) continue;
- if (ds->value->used == 0) continue;
-
- if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
+ /* Fill in the fromhost bits of the request struct */
+ fromhost(&request);
+ /* Access blocked by tcp wrappers */
+ if(!hosts_access(&request)) {
con->http_status = 403;
-
return HANDLER_FINISHED;
- }
}
- /* not found */
+ /* Access allowed */
return HANDLER_GO_ON;
}
/* this function is called at dlopen() time and inits the callbacks */
-int mod_skeleton_plugin_init(plugin *p) {
+int mod_tcpwrapper_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
- p->name = buffer_init_string("skeleton");
+ p->name = buffer_init_string("tcpwrapper");
- p->init = mod_skeleton_init;
- p->handle_uri_clean = mod_skeleton_uri_handler;
- p->set_defaults = mod_skeleton_set_defaults;
- p->cleanup = mod_skeleton_free;
+ p->init = mod_tcpwrapper_init;
+ p->handle_uri_clean = mod_tcpwrapper_uri_handler;
+ p->set_defaults = mod_tcpwrapper_set_defaults;
+ p->cleanup = mod_tcpwrapper_free;
p->data = NULL;
You can download a tarball with the source code, config files and instructions as well as pre-compiled modules for i386 and sparc (compiled for Debian squeeze) at this link mod_tcpwrapper.tgz
[/lighttpd] permanent link RSS feed