Date: Mon, 20 Mar 2006 15:49:08 +1100 (EST) From: Maurice Castro <maurice@sphinx.clari.net.au> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/94715: modification to mail/spamd port to use ipfw Message-ID: <200603200449.k2K4n8Tf018205@sphinx.clari.net.au> Resent-Message-ID: <200603200450.k2K4oF15054881@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 94715 >Category: ports >Synopsis: modification to mail/spamd port to use ipfw >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Mar 20 04:50:15 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Maurice Castro >Release: FreeBSD 5.4-RELEASE i386 >Organization: Calrinet Internet Solutions >Environment: System: FreeBSD sphinx.clari.net.au 5.4-RELEASE FreeBSD 5.4-RELEASE #1: Wed Nov 30 11:05:23 EST 2005 mjb@sphinx.clari.net.au:/work/src/sys/i386/compile/sphinx i386 All FreeBSD post 4.9 >Description: Patch for mail/spamd port to allow compilation with make -DIPFW to generate a version of spamd that works without the need for pf. >How-To-Repeat: Apply patch >Fix: diff -urN /usr/ports/mail/spamd/Makefile spamd_new/Makefile --- /usr/ports/mail/spamd/Makefile Mon Jul 18 13:24:33 2005 +++ spamd_new/Makefile Fri Mar 17 16:40:03 2006 @@ -19,11 +19,19 @@ .include <bsd.port.pre.mk> +.if defined(IPFW) +CFLAGS+= -DIPFW +.if ${OSVERSION} < 490000 +IGNORE= IPFW with Tables is required for this port to function properly +.endif +.else .if ${OSVERSION} < 502117 IGNORE= OpenBSD 3.5 pf/pfctl is necessary for this port to function properly. .else LOCAL_PFCTL= /sbin/pfctl .endif +.endif + USE_RC_SUBR= yes RC_SCRIPTS_SUB= PREFIX=${PREFIX} RC_SUBR=${RC_SUBR} @@ -46,7 +54,7 @@ @${REINPLACE_CMD} -e 's|/etc/spamd.conf|${PREFIX}/etc/spamd.conf|' \ ${WRKSRC}/spamd/spamd.8 ${WRKSRC}/spamd-setup/spamd-setup.8 @${SED} ${RC_SCRIPTS_SUB:S/$/!g/:S/^/ -e s!%%/:S/=/%%!/} \ - ${FILESDIR}/pfspamd.sh > ${WRKDIR}/pfspamd.sh + ${FILESDIR}/pfspamd.sh > ${WRKDIR}/pfspamd.sh pre-su-install: .if !defined(BATCH) && !defined(PACKAGE_BUILDING) @@ -63,11 +71,11 @@ ${INSTALL_MAN} ${WRKSRC}/spamd-setup/spamd-setup.8 ${PREFIX}/man/man8 ${INSTALL_MAN} ${WRKSRC}/spamdb/spamdb.8 ${PREFIX}/man/man8 ${INSTALL_MAN} ${WRKSRC}/spamlogd/spamlogd.8 ${PREFIX}/man/man8 - @${INSTALL_SCRIPT} -m 555 ${WRKDIR}/pfspamd.sh ${PREFIX}/etc/rc.d/pfspamd.sh @if [ ! -f ${SAMPLE_SPAMD_CONF} ]; then \ ${ECHO_MSG} "Installing ${SAMPLE_SPAMD_CONF} file."; \ ${INSTALL_DATA} ${WRKSRC}/doc/spamd.conf \ ${SAMPLE_SPAMD_CONF}; \ fi + @${INSTALL_SCRIPT} -m 555 ${WRKDIR}/pfspamd.sh ${PREFIX}/etc/rc.d/pfspamd.sh .include <bsd.port.post.mk> diff -urN /usr/ports/mail/spamd/files/patch-greyc spamd_new/files/patch-greyc --- /usr/ports/mail/spamd/files/patch-greyc Thu Jan 1 10:00:00 1970 +++ spamd_new/files/patch-greyc Mon Mar 20 15:33:11 2006 @@ -0,0 +1,131 @@ +--- spamd/grey.c Wed Apr 13 03:22:17 2005 ++++ spamd/grey.c Mon Mar 20 15:26:18 2006 +@@ -39,6 +39,10 @@ + #include <unistd.h> + #include <netdb.h> + ++#ifdef IPFW ++#include <netinet/ip_fw.h> ++#endif ++ + #include "grey.h" + + extern time_t passtime, greyexp, whiteexp, trapexp; +@@ -65,13 +69,17 @@ + char *traplist_msg = "\"Your address %A has mailed to spamtraps here\\n\""; + + pid_t db_pid = -1; +-int pfdev; + int spamdconf; + ++#ifdef IPFW ++extern int tabno; ++#else ++int pfdev; + static char *pargv[11]= { + "pfctl", "-p", "/dev/pf", "-q", "-t", + "spamd-white", "-T", "replace", "-f" "-", NULL + }; ++#endif + + /* If the parent gets a signal, kill off the children and exit */ + /* ARGSUSED */ +@@ -104,6 +112,7 @@ + return(0); + } + ++#ifndef IPFW + int + configure_pf(char **addrs, int count) + { +@@ -166,11 +175,54 @@ + for (i = 0; i < count; i++) + if (addrs[i] != NULL) + fprintf(pf, "%s/32\n", addrs[i]); ++ + fclose(pf); + waitpid(pid, NULL, 0); + sigaction(SIGCHLD, &sa, NULL); + return(0); + } ++#else ++int ++configure_pf(char **addrs, int count) ++{ ++ int s = -1; ++ ipfw_table_entry ent; ++ int i; ++ ++ if (s == -1) ++ s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); ++ if (s < 0) ++ { ++ syslog_r(LOG_INFO, &sdata, "IPFW socket unavailable (%m)"); ++ return(-1); ++ } ++ ++ /* flush the table */ ++ ent.tbl = tabno; ++ if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_FLUSH, &ent.tbl, sizeof(ent.tbl)) < 0) ++ { ++ syslog_r(LOG_INFO, &sdata, "IPFW setsockopt(IP_FW_TABLE_FLUSH) (%m)"); ++ return(-1); ++ } ++ ++ for (i = 0; i < count; i++) ++ if (addrs[i] != NULL) ++ { ++ /* add addrs[i] to tabno */ ++ ent.tbl = tabno; ++ ent.masklen = 32; ++ ent.value = 0; ++ inet_aton(addrs[i], (struct in_addr *)&ent.addr); ++ if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_ADD, &ent, sizeof(ent)) < 0) ++ { ++ syslog_r(LOG_INFO, &sdata, "IPFW setsockopt(IP_FW_TABLE_ADD) (%m)"); ++ return(-1); ++ } ++ } ++ ++ return(0); ++} ++#endif + + void + freeaddrlists(void) +@@ -590,11 +642,13 @@ + int i; + struct sigaction sa; + ++#ifndef IPFW + pfdev = open("/dev/pf", O_RDWR); + if (pfdev == -1) { + syslog_r(LOG_ERR, &sdata, "open of /dev/pf failed (%m)"); + exit(1); + } ++#endif + + /* check to see if /var/db/spamd exists, if not, create it */ + if ((i = open(PATH_SPAMD_DB, O_RDWR, 0)) == -1 && errno == ENOENT) { +@@ -636,7 +690,9 @@ + * child, talks to jailed spamd over greypipe, + * updates db. has no access to pf. + */ ++#ifndef IPFW + close(pfdev); ++#endif + setproctitle("(%s update)", PATH_SPAMD_DB); + greyreader(); + /* NOTREACHED */ +@@ -655,7 +711,11 @@ + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + ++#ifndef IPFW + setproctitle("(pf <spamd-white> update)"); ++#else ++ setproctitle("(ipfw white table update)"); ++#endif + greyscanner(); + /* NOTREACHED */ + exit(1); diff -urN /usr/ports/mail/spamd/files/patch-greyh spamd_new/files/patch-greyh --- /usr/ports/mail/spamd/files/patch-greyh Thu Jan 1 10:00:00 1970 +++ spamd_new/files/patch-greyh Thu Mar 16 21:18:51 2006 @@ -0,0 +1,10 @@ +--- spamd/grey.h Thu Mar 16 19:55:33 2006 ++++ spamd/grey.h Thu Mar 16 19:55:56 2006 +@@ -22,6 +22,7 @@ + #define WHITEEXP (60 * 60 * 24 * 36) /* remove white entries after 36 days */ + #define TRAPEXP (60 * 60 * 24) /* hitting a spamtrap blacklists for a day */ + #define PATH_PFCTL "/sbin/pfctl" ++#define PATH_IPFW "/sbin/ipfw" + #define DB_SCAN_INTERVAL 60 + #define PATH_SPAMD_DB "/var/db/spamd" + diff -urN /usr/ports/mail/spamd/files/patch-spamd spamd_new/files/patch-spamd --- /usr/ports/mail/spamd/files/patch-spamd Thu Jan 1 10:00:00 1970 +++ spamd_new/files/patch-spamd Fri Mar 17 08:20:06 2006 @@ -0,0 +1,48 @@ +--- spamd/spamd.c Thu Mar 16 20:56:45 2006 ++++ spamd/spamd.c Thu Mar 16 21:07:11 2006 +@@ -123,6 +123,10 @@ + pid_t jail_pid = -1; + u_short cfg_port; + ++#ifdef IPFW ++int tabno=1; ++#endif ++ + extern struct sdlist *blacklists; + + int conffd = -1; +@@ -153,6 +157,10 @@ + " [-G mins:hours:hours] [-n name] [-p port]\n"); + fprintf(stderr, + " [-r reply] [-s secs] [-w window]\n"); ++#ifdef IPFW ++ fprintf(stderr, ++ " [-t table_no]\n"); ++#endif + exit(1); + } + +@@ -958,7 +966,11 @@ + if (gethostname(hostname, sizeof hostname) == -1) + err(1, "gethostname"); + ++#ifdef IPFW ++ while ((ch = getopt(argc, argv, "45b:c:B:p:dgG:r:s:n:vw:t:")) != -1) { ++#else + while ((ch = getopt(argc, argv, "45b:c:B:p:dgG:r:s:n:vw:")) != -1) { ++#endif + switch (ch) { + case '4': + nreply = "450"; +@@ -1015,6 +1027,11 @@ + case 'v': + verbose = 1; + break; ++#ifdef IPFW ++ case 't': ++ tabno = atoi(optarg); ++ break; ++#endif + case 'w': + window = atoi(optarg); + if (window <= 0) diff -urN /usr/ports/mail/spamd/files/patch-spamd-setup spamd_new/files/patch-spamd-setup --- /usr/ports/mail/spamd/files/patch-spamd-setup Thu Jan 1 10:00:00 1970 +++ spamd_new/files/patch-spamd-setup Mon Mar 20 15:33:22 2006 @@ -0,0 +1,115 @@ +--- spamd-setup/spamd-setup.c Wed Apr 13 03:18:59 2005 ++++ spamd-setup/spamd-setup.c Fri Mar 17 16:19:25 2006 +@@ -41,9 +41,14 @@ + #include <netdb.h> + #include <zlib.h> + ++#ifdef IPFW ++#include <net/if.h> ++#include <netinet/ip_fw.h> ++#endif ++ + #define PATH_FTP "/usr/bin/ftp" +-#define PATH_PFCTL "%%LOCAL_PFCTL%%" +-#define PATH_SPAMD_CONF "%%LOCAL_SPAMD_CONF%%" ++#define PATH_PFCTL "" ++#define PATH_SPAMD_CONF "/usr/local/etc/spamd.conf" + #define SPAMD_ARG_MAX 256 /* max # of args to an exec */ + + struct cidr { +@@ -93,6 +98,11 @@ + int debug; + int dryrun; + ++#ifdef IPFW ++int tabno=2; ++#endif ++ ++ + u_int32_t + imask(u_int8_t b) + { +@@ -630,6 +640,7 @@ + } + + ++#ifndef IPFW + int + configure_pf(struct cidr **blacklists) + { +@@ -676,6 +687,51 @@ + } + return(0); + } ++#else ++int ++configure_pf(struct cidr **blacklists) ++{ ++ int s = -1; ++ ipfw_table_entry ent; ++ ++ if (s == -1) ++ s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); ++ if (s < 0) ++ { ++ err(1, "IPFW socket unavailable"); ++ return(-1); ++ } ++ ++ /* flush the table */ ++ ent.tbl = tabno; ++ if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_FLUSH, &ent.tbl, sizeof(ent.tbl)) < 0) ++ { ++ err(1, "IPFW setsockopt(IP_FW_TABLE_FLUSH)"); ++ return(-1); ++ } ++ ++ while (*blacklists != NULL) { ++ struct cidr *b = *blacklists; ++ ++ while (b->addr != 0) { ++ /* add b to tabno */ ++ ent.tbl = tabno; ++ ent.masklen = b->bits; ++ ent.value = 0; ++ inet_aton(atop(b->addr), (struct in_addr *)&ent.addr); ++ if (setsockopt(s, IPPROTO_IP, IP_FW_TABLE_ADD, &ent, sizeof(ent)) < 0) ++ { ++ err(1, "IPFW setsockopt(IP_FW_TABLE_ADD)"); ++ return(-1); ++ } ++ b++; ++ } ++ blacklists++; ++ } ++ ++ return(0); ++} ++#endif + + int + getlist(char ** db_array, char *name, struct blacklist *blist, +@@ -773,7 +829,11 @@ + struct servent *ent; + int i, ch; + ++#ifndef IPFW + while ((ch = getopt(argc, argv, "nd")) != -1) { ++#else ++ while ((ch = getopt(argc, argv, "ndt")) != -1) { ++#endif + switch (ch) { + case 'n': + dryrun = 1; +@@ -781,6 +841,11 @@ + case 'd': + debug = 1; + break; ++#ifdef IPFW ++ case 't': ++ tabno = atoi(optarg); ++ break; ++#endif + default: + break; + } diff -urN /usr/ports/mail/spamd/files/patch-spamdm spamd_new/files/patch-spamdm --- /usr/ports/mail/spamd/files/patch-spamdm Thu Jan 1 10:00:00 1970 +++ spamd_new/files/patch-spamdm Mon Mar 20 15:36:57 2006 @@ -0,0 +1,89 @@ +--- spamd/spamd.8 Wed Apr 13 03:21:48 2005 ++++ spamd/spamd.8 Mon Mar 20 15:12:10 2006 +@@ -49,6 +49,8 @@ + daemon which rejects false mail. + If the + .Xr pf 4 ++or ++.Xr ipfw 4 + packet filter is configured to redirect port 25 (SMTP) to this daemon, + it will attempt to waste the time and resources of the spam sender. + .Pp +@@ -151,11 +153,15 @@ + which processes a list of spammers' addresses, and applies appropriate + .Xr pfctl 8 + .Em rdr ++or ++.Xr ipfw 8 ++.Em fwd + rules. + .Xr spamd-setup 8 + is run from + .Xr cron 8 . + .Sh REDIRECTING SMTP CONNECTIONS ++.Ss "When using PF" + With + .Xr pf 4 , + connections to port 25 (SMTP) can be redirected to another host or port, +@@ -189,6 +195,8 @@ + can also be used to load addresses into the + .Em <spamd> + table. ++ ++ + .Xr spamd-setup 8 + also has the added benefit of being able to remove addresses from + blacklists, and will connect to +@@ -203,6 +211,52 @@ + This is important as it allows legitimate mail + senders to pressure spam sources into behaving properly so that they + may be removed from the relevant blacklists. ++ ++.Ss "If compiled with IPFW" ++With ++.Xr ipfw 4 , ++the syntax for redirection of TCP sessions is quite different ++from that of ++.Xr pf 4 . ++The ++.Em fwd ++rule used for this purpose are described in ++.Xr ipfw 8 . ++The rules should be added to the ruleset called by /etc/rc.firewall ++to be present at boot time. ++.Bd -literal -offset 4n ++fwd 127.0.0.1,8025 tcp from table(2) to me 25 in ++allow tcp from table(1) to me 25 in ++fwd 127.0.0.1,8025 tcp from any to me 25 in ++.Ed ++.Pp ++Any addresses in the blacklist table ++.Em 2 ++and not in the whitelist table ++.Em 1 ++are then redirected to ++.Nm ++running on port 8025. ++Addresses can be loaded into the blacklist ++.Em table , ++like: ++.Bd -literal -offset 4n ++# ipfw table 1 add a.b.c.d/x ++.Ed ++.Pp ++.Xr spamd-setup 8 ++can also be used to load addresses into the blacklist table ++.Em 2 . ++.Pp ++The ++.Op Fl t Ar table_no ++option to ++.Em spamd ++and ++.Em spamd-setup ++can be used to change the default table ++numbers. ++ + .Sh CONFIGURATION CONNECTIONS + .Nm + listens for configuration connections on the port identified by the diff -urN /usr/ports/mail/spamd/pkg-message spamd_new/pkg-message --- /usr/ports/mail/spamd/pkg-message Thu Jan 13 13:54:46 2005 +++ spamd_new/pkg-message Mon Mar 20 10:44:13 2006 @@ -1,9 +1,18 @@ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -In order to use spamd greylisting feature you have to have a mounted fdescfs(5) -at /dev/fd. This is done by adding: +In order to use spamd greylisting feature with pf firewall you have to have a +mounted fdescfs(5) at /dev/fd. This is done by adding: fdescfs /dev/fd fdescfs rw 0 0 to /etc/fstab. You may need either a customised kernel, or kldload the fdescfs kernel module. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +To use spamd with ipfw firewall, simply include ipfw rules similar to the +following: + +00400 fwd tcp from table(2) to any dst-port 25 +00410 allow tcp from table(1) to any dst-port 25 +00420 fwd 127.0.0.1,8025 tcp from any to any dst-port 25 in + +Other table numbers can be used by using the -t option to spamd and spamd-setup ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200603200449.k2K4n8Tf018205>