| Newsgroups |
gmane.comp.neostats.devel |
| Message-ID |
<[email protected]> |
Author: Fish
Date: Thu Aug 4 21:16:06 2005
New Revision: 14
Added:
DNS_Proc.c
Makefile
dblogin.h.in
Log:
import DNSBL_Proc processor for Secure Blacklist support
Added: DNS_Proc.c
==============================================================================
--- (empty file)
+++ DNS_Proc.c Thu Aug 4 21:16:06 2005
@@ -0,0 +1,353 @@
+/*
+ * udp-get.c: receive from UDP and send to stdout
+ *
+ * Copyright (c) 2000 Alessandro Rubini (rubini-mXXj517/[email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <fcntl.h>
+#include <dbi/dbi.h>
+#include <pcre/pcre.h>
+#include <libgen.h>
+#include <adns.h>
+#include <assert.h>
+
+#include "dblogin.h"
+
+#define MAXDNS 500
+
+
+dbi_conn conn;
+
+struct stats {
+ unsigned long entries;
+ unsigned long processed;
+ unsigned long dnslookups;
+ unsigned long dnsfailures;
+ unsigned long dnsdone;
+ unsigned long straightinserts;
+ unsigned long dullookups;
+ unsigned long duldone;
+ unsigned long dulfailed;
+} stats;
+
+int currentadns;
+
+adns_state ads;
+
+typedef struct dnsentry {
+ struct in_addr *inp;
+ char ip[17];
+ char *hostname;
+ unsigned long id;
+ unsigned long count;
+ adns_query q;
+ adns_answer *a;
+ enum {
+ IPLOOKUP,
+ DULLOOKUP,
+ } dnstype;
+ int score;
+} dnsentry;
+
+
+int score[] = {
+ 0, /* NULL 127.0.0.0 */
+ 0, /* NULL 127.0.0.1 */
+ 4, /* http.dnsbl.sorbs.net 127.0.0.2 */
+ 4, /* socks.dnsbl.sorbs.net 127.0.0.3 */
+ 4, /* misc.dnsbl.sorbs.net 127.0.0.4 */
+ 1, /* smtp.dnsbl.sorbs.net 127.0.0.5 */
+ 3, /* spam.dnsbl.sorbs.net 127.0.0.6 */
+ 4, /* web.dnsbl.sorbs.net 127.0.0.7 */
+ 0, /* block.dnsbl.sorbs.net 127.0.0.8 */
+ 5, /* zombie.dnsbl.sorbs.net 127.0.0.9 */
+ -2, /* dul.dnsbl.sorbs.net 127.0.0.10 */
+ 0, /* badconf.rhsbl.sorbs.net 127.0.0.11 */
+ 0, /* nomail.rhsbl.sorbs.net 127.0.0.12 */
+};
+
+
+
+void db_error(dbi_conn dbcon, void *unused) {
+ const char *errormsg;
+ dbi_conn_error(dbcon, &errormsg);
+ fprintf(stderr, "\nDatabase Error: %s\n\n", errormsg);
+}
+
+void do_insert(dnsentry *entry) {
+ dbi_result result;
+ result = dbi_conn_queryf(conn, "insert into blacklist (ipaddr, viri, detected, score) values ('%s', '%ld', '%ld', '%d') on duplicate key update detected=detected+%ld", entry->ip, entry->id, entry->count, entry->count, entry->score);
+ if (dbi_result_get_numrows_affected(result) == 0) {
+ fprintf(stderr, "\nFailed Update of %s\n\n", entry->ip);
+ }
+ stats.processed++;
+ dbi_result_free(result);
+ free(entry->inp);
+ free(entry->hostname);
+ free(entry);
+}
+
+void do_dullookup(dnsentry *entry, struct in_addr inp) {
+ unsigned char a, b, c, d;
+ char buf[255];
+ int i;
+
+ d = (unsigned char) ( inp.s_addr >> 24 ) & 0xFF;
+ c = (unsigned char) ( inp.s_addr >> 16 ) & 0xFF;
+ b = (unsigned char) ( inp.s_addr >> 8 ) & 0xFF;
+ a = (unsigned char) ( inp.s_addr & 0xFF );
+ snprintf(buf, 255, "%d.%d.%d.%d.dnsbl.sorbs.net", d,c,b,a);
+ free(entry->hostname);
+ entry->hostname = strndup(buf, strlen(buf));
+ stats.dullookups++;
+ currentadns++;
+ entry->dnstype = DULLOOKUP;
+ i = adns_submit (ads, entry->hostname, adns_r_a, adns_qf_owner | adns_qf_cname_loose, entry, &entry->q);
+ if (i) {
+ stats.dulfailed++;
+ fprintf(stderr, "\nDNS Error: %s\n\n", strerror(i));
+ free(entry->inp);
+ free(entry->hostname);
+ free(entry);
+ }
+
+
+}
+
+void check_adns() {
+ int i, j;
+ dnsentry *entry;
+ adns_query q;
+ void *ctx;
+ struct in_addr inp;
+
+ adns_processany(ads);
+ for (adns_forallqueries_begin(ads); (q=adns_forallqueries_next(ads, &ctx));) {
+ entry = ctx;
+ assert(entry->q == q);
+ if (!entry) {
+ continue;
+ }
+ i = adns_check(ads, &entry->q, (void *)&entry->a, NULL);
+ if (entry->dnstype == IPLOOKUP) {
+ if (i == EAGAIN) {
+ /* do nothing */
+ } else if (i) {
+ fprintf(stderr, "\nDNS Error on %s: %s\n\n", entry->hostname, strerror(i));
+ free(entry->inp);
+ free(entry->hostname);
+ free(entry);
+ currentadns--;
+ stats.dnsfailures++;
+ } else if ((entry->a) && (entry->a->nrrs > 0) && (entry->a->status == adns_s_ok)) {
+ inp.s_addr = entry->a->rrs.addr->addr.inet.sin_addr.s_addr;
+ strncpy (entry->ip, inet_ntoa (inp), 17);
+ do_dullookup(entry, inp);
+ currentadns--;
+ stats.dnsdone++;
+ } else if (entry->a->status != adns_s_ok) {
+ free(entry->inp);
+ free(entry->hostname);
+ free(entry);
+ stats.dnsfailures++;
+ currentadns--;
+ }
+ } else {
+ if (i == EAGAIN) {
+ /* do nothing */
+ } else if (i) {
+ fprintf(stderr, "\nDULDNS Error on %s: %s\n\n", entry->hostname, strerror(i));
+ /* even though its a error, just insert anyway */
+ do_insert(entry);
+ currentadns--;
+ stats.dulfailed++;
+ } else if ((entry->a) && (entry->a->nrrs > 0) && (entry->a->status == adns_s_ok)) {
+ for (i = 0; i < entry->a->nrrs; i++) {
+ inp = *((struct in_addr*)&entry->a->rrs.inaddr[i] );
+ j = (unsigned char) ( inp.s_addr >> 24 ) & 0xFF;
+ entry->score += score[j];
+ }
+ do_insert(entry);
+ currentadns--;
+ stats.duldone++;
+ } else if (entry->a->status == adns_s_nxdomain) {
+ /* doesn't exist, means its clean */
+ do_insert(entry);
+ stats.duldone++;
+ currentadns--;
+ } else if (entry->a->status != adns_s_ok) {
+ printf("\nfailed %s %s\n\n", entry->hostname, adns_strerror(entry->a->status));
+ do_insert(entry);
+ stats.dulfailed++;
+ currentadns--;
+ }
+ }
+ }
+
+}
+
+
+int main(int argc, char **argv)
+{
+ dbi_result result;
+ unsigned long lastidx, maxidx, testidx;
+ unsigned long lastblidx, curblidx;
+ int i;
+ dnsentry *entry;
+
+ /* setup the db connection */
+
+ dbi_initialize(NULL);
+
+ conn = dbi_conn_new("mysql");
+ if (!conn) {
+ fprintf(stdout, "%s: Can not create new DBI\n", argv[0]);
+ exit(1);
+ }
+ dbi_conn_error_handler(conn, db_error, NULL);
+
+ dbi_conn_set_option(conn, "host", DBHOST);
+ dbi_conn_set_option(conn, "username", DBLOGIN);
+ dbi_conn_set_option(conn, "password", DBPASS);
+ dbi_conn_set_option(conn, "dbname", DB);
+ dbi_conn_connect(conn);
+
+ if ((i = adns_init (&ads, 0, 0))) {
+ fprintf(stderr, "ADNS init failed: %s", strerror (i));
+ exit(-1);
+ }
+
+
+
+
+ lastidx = maxidx = lastblidx = curblidx = 0;
+ /* get the last entry we processed */
+ fprintf(stdout, "Starting %s\n", (char *)basename((char *)argv[0]));
+
+ result = dbi_conn_query(conn, "SELECT value from settings where settings.name = 'DNSBL_LastIDX_Processed'");
+ if (dbi_result_get_numrows(result) > 0) {
+ dbi_result_next_row(result);
+ lastidx = atol(dbi_result_get_string(result, "value"));
+ } else {
+ fprintf(stderr, "Error, No Last Index Processed Field in Settings Table. Aborting\n");
+ exit(-1);
+ }
+ dbi_result_free(result);
+
+ result = dbi_conn_query(conn, "SELECT value from settings where settings.name = 'DNSBL_BLIDX_Processed'");
+ if (dbi_result_get_numrows(result) > 0) {
+ dbi_result_next_row(result);
+ lastblidx = atol(dbi_result_get_string(result, "value"));
+ } else {
+ fprintf(stderr, "Error, No Last Index Processed Field in Settings Table. Aborting\n");
+ exit(-1);
+ }
+ dbi_result_free(result);
+
+ result = dbi_conn_query(conn, "SELECT max(idxNum) as value from blacklist;");
+ if (dbi_result_get_numrows(result) > 0) {
+ dbi_result_next_row(result);
+ curblidx = dbi_result_get_long(result, "value");
+ }
+ dbi_result_free(result);
+
+
+ /* ok, compare curentBL with lastblidx */
+ if (curblidx > lastblidx) {
+ fprintf(stderr, "Ehhh, Last run probably didn't complete. Rolling back...");
+ result = dbi_conn_queryf(conn, "delete from blacklist where idxNum > '%ld'", lastblidx);
+ if (dbi_result_get_numrows_affected(result) <= 0) {
+ fprintf(stderr, "Failed to Reset Table... Exiting\n");
+ exit(-1);
+ }
+ dbi_result_free(result);
+ fprintf(stderr, "done\n");
+ }
+
+
+ /* ok, now start the selection */
+ result = dbi_conn_queryf(conn, "select hosts.idxNum, hostName, defs.id, sum(hosts.count) as mycnt from hosts, defs where hosts.viri=defs.name and defs.action != 3 and hosts.idxNum > '%ld' group by hostname limit 10000;", lastidx);
+ stats.entries = dbi_result_get_numrows(result);
+ fprintf(stdout, "Processing %ld Entries\n", stats.entries);
+ currentadns = 0;
+ while (dbi_result_next_row(result) != 0) {
+ dbi_result_next_row(result);
+ entry = malloc(sizeof(dnsentry));
+ entry->inp = malloc(sizeof(struct in_addr));
+ entry->hostname = strdup(dbi_result_get_string(result, "hostname"));
+ entry->id = dbi_result_get_long(result, "id");
+ entry->count = dbi_result_get_double(result, "mycnt");
+ testidx = dbi_result_get_long(result, "idxNum");
+ if (testidx > maxidx) maxidx = testidx;
+ entry->score = 0;
+ if (inet_aton(entry->hostname, entry->inp)) {
+ snprintf(entry->ip, 16, "%s", entry->hostname);
+ stats.straightinserts++;
+ do_dullookup(entry, *entry->inp);
+ } else {
+ while (currentadns >= MAXDNS) {
+ check_adns();
+ fprintf(stdout, "DNSQ: %d* OK: %ld IP: %ld IP-DONE: %ld IP-FAIL: %ld DUL-DNS: %ld DUL-DONE: %ld DUL-FAIL: %ld PRCD: %ld \r", currentadns, stats.straightinserts, stats.dnslookups, stats.dnsdone, stats.dnsfailures, stats.dullookups, stats.duldone, stats.dulfailed, stats.processed);
+ }
+ stats.dnslookups++;
+ currentadns++;
+ entry->dnstype = IPLOOKUP;
+ i = adns_submit (ads, entry->hostname, adns_r_addr, adns_qf_owner | adns_qf_cname_loose, entry, &entry->q);
+ if (i) {
+ fprintf(stderr, "\nDNS Error: %s\n\n", strerror(i));
+ free(entry->inp);
+ free(entry->hostname);
+ free(entry);
+ }
+ }
+ fprintf(stdout, "DNSQ: %d OK: %ld IP: %ld IP-DONE: %ld IP-FAIL: %ld DUL-DNS: %ld DUL-DONE: %ld DUL-FAIL: %ld PRCD: %ld \r", currentadns, stats.straightinserts, stats.dnslookups, stats.dnsdone, stats.dnsfailures, stats.dullookups, stats.duldone, stats.dulfailed, stats.processed);
+ check_adns();
+ }
+
+ while (currentadns != 0) {
+ fprintf(stdout, "DNSQ: %d* OK: %ld IP: %ld IP-DONE: %ld IP-FAIL: %ld DUL-DNS: %ld DUL-DONE: %ld DUL-FAIL: %ld PRCD: %ld \r", currentadns, stats.straightinserts, stats.dnslookups, stats.dnsdone, stats.dnsfailures, stats.dullookups, stats.duldone, stats.dulfailed, stats.processed);
+ check_adns();
+ }
+ fprintf(stdout, "\n");
+ dbi_result_free(result);
+
+ dbi_conn_close(conn);
+ dbi_shutdown();
+
+ printf("Processed %ld Entries, %ld straight inserts, %ld DNS lookups started, %ld DNS lookups failed\n", stats.processed, stats.straightinserts, stats.dnslookups, stats.dnsfailures);
+
+
+ dbi_conn_query(conn, "update settings, blacklist set settings.value=max(blacklist.idxNum) where settings.name='DNSBL_BLIDX_Processed'");
+ dbi_conn_queryf(conn, "update settings, blacklist set settings.value='%ld' where settings.name='DNSBL_LastIDX_Processed'", maxidx);
+
+
+ exit(1);
+}
Added: Makefile
==============================================================================
--- (empty file)
+++ Makefile Thu Aug 4 21:16:06 2005
@@ -0,0 +1,28 @@
+#Neostats Module Makefile!
+CC=gcc
+CFLAGS= -O2 -ggdb -Wall
+LDFLAGS= -lpcre -ldl -ldbi -lcrypt -ladns
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+
+SOURCES= DNS_Proc.c
+OBJECTS= DNS_Proc.o
+TARGET= DNS_Proc
+DOCS=
+DATA=
+
+
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCLUDES) $<
+
+default: $(OBJECTS)
+ $(CC) -o $(TARGET) $(OBJECTS) $(LDFLAGS)
+
+clean:
+ /bin/rm -rf $(TARGET) *.o *.log
+
+$(OBJECTS): Makefile
+
+DNS_Proc.o: DNS_Proc.c
Added: dblogin.h.in
==============================================================================
--- (empty file)
+++ dblogin.h.in Thu Aug 4 21:16:06 2005
@@ -0,0 +1,10 @@
+#ifndef DBLOGIN_H
+#define DBLOGIN_H
+
+/* this is the database login info */
+#define DBHOST "localhost"
+#define DBLOGIN "mysql"
+#define DBPASS "mysql"
+#define DB "mysql"
+
+#endif