On 2013-W10-4 15:08 -0700, Bob Beck wrote:

Show me your pf.conf please - I'd like to address your problem
in the documentation or another way.. I don't like a knob like
this.

According to pf.conf(5), you can only log to one pflog(4) interface at a time, so, it's not exactly trivial to modify the rules, without modifying the rest of the workflow.

BTW, don't laugh at these rules. They're highly effective, 99,9% of my incoming mail does not go through greylisting at all whatsoever, yet all spammers always end up talking to spamd. Some of these may seem redundant or a noop, they're mostly used for statistic purposes, just as you use spamlogd to whitelist already whitelisted netblocks, and see how much mail individual IPs send / receive.

As for documentation, I think it's counterintuitive that `tcpdump` shows rewritten addresses / ports, yet spamlogd pcap(3) filter operates on the original ones. So, I know spamlogd(8) says what it says, but after running tcpdump on /var/log/pflog, it makes absolutely no sense that spamlogd would be whitelisting all of those connections that are redirected to spamd. (It also makes no sense how spamd -M works with the rules as they are below (although I'm very glad that it does, and works great at that).)

I think this should not only be addressed in the documentation (for pcap-filter, spamd -M / spamlogd, pf.conf log/rdr-to / pflogd, tcpdump), but in the actual spamlogd code changes, too -- it should be smart enough to not automatically whitelist the connections that are rewritten to the default spamd port.

Best regards,
Constantine.


# overall policy:
# * always pass BSD, regardless of IP
# * greylist all win, and non-a/r, and trap anyone
pass in log on re0 proto tcp from any to any port smtp label "smtp any / other"
pass in log on re0 proto tcp from any os "Windows .NET" to any port smtp label "smtp 
Windows .NET"
pass in log on re0 proto tcp from any os Windows to any port smtp label "smtp 
Windows" \
   rdr-to 127.0.0.1 port spamd
pass in log on re0 proto tcp from any os Linux to any port smtp label "smtp 
Linux"
pass in quick log on re0 proto tcp from any os FreeBSD to any port smtp label "smtp 
FreeBSD"
pass in quick log on re0 proto tcp from any os NetBSD to any port smtp label "smtp 
NetBSD"
pass in quick log on re0 proto tcp from any os OpenBSD to any port smtp label "smtp 
OpenBSD"
pass in log on re0 proto tcp from any os unknown to any port smtp label "smtp 
unknown"

# rules for spamd(8)
block return in quick log proto tcp from any to any port 8025
table <spamd-white> persist
#table <nospamd> persist file "/etc/mail/nospamd"
#pass in on egress proto tcp from any to any port smtp \
#    rdr-to 127.0.0.1 port spamd
pass in on egress proto tcp from {<apnic>,<lacnic>,<afrinic>} to any port smtp \
   rdr-to 127.0.0.1 port spamd
pass in on egress proto tcp from any to spamd.mx.example.su port smtp \
   rdr-to 127.0.0.1 port spamd
#pass in on egress proto tcp from <nospamd> to any port smtp
pass in log on egress proto tcp from <spamd-white> to any port smtp
pass out log on egress proto tcp to any port smtp




On Thu, Mar 07, 2013 at 12:04:22PM -0800, Constantine A. Murenin wrote:
> On 2013-W10-3 15:46 -0700, Bob Beck wrote:
> > > Yes, one could log stuff into different pflog interfaces, but I don't
> > > understand why pf.conf `pass in ... log ... port smtp ...` is effectively
> > > redefined to mean `add <spamd-white>` when spamlogd is running,
> > > > http://www.openbsd.org/cgi-bin/man.cgi?query=spamlogd > > > > and RTFM for the first two sentences - and it's pretty darn clear. > > > > Those of us that whitelist blocks of addresses (and log them) like
> > this behaviour to track what mailservers we are seeing like the
> > current behavior.
> > Point taken; this should be optional.

> Index: spamlogd.8
> ===================================================================
> RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.8,v
> retrieving revision 1.17
> diff -u -d -p -8 -r1.17 spamlogd.8
> --- spamlogd.8     4 Mar 2011 21:01:49 -0000       1.17
> +++ spamlogd.8     7 Mar 2013 19:41:24 -0000
> @@ -17,17 +17,17 @@
>  .Dd $Mdocdate: March 4 2011 $
>  .Dt SPAMLOGD 8
>  .Os
>  .Sh NAME
>  .Nm spamlogd
>  .Nd spamd whitelist updating daemon
>  .Sh SYNOPSIS
>  .Nm spamlogd
> -.Op Fl DI
> +.Op Fl DIU
>  .Op Fl i Ar interface
>  .Op Fl l Ar pflog_interface
>  .Op Fl W Ar whiteexp
>  .Op Fl Y Ar synctarget
>  .Sh DESCRIPTION
>  .Nm
>  manipulates the
>  .Xr spamd 8
> @@ -73,16 +73,32 @@ target of outbound SMTP connections.
>  Specify a network interface on which packets must arrive.
>  The default is to watch for connections logged from all interfaces.
>  .It Fl l Ar pflog_interface
>  Specify a
>  .Xr pflog 4
>  interface to listen for connection notifications.
>  The default is to watch for connections logged on
>  .Dq pflog0 .
> +.It Fl U
> +Specify that for inbound SMTP connections,
> +.Nm
> +is only to update existing
> +.Pa /var/db/spamd
> +entries, without adding any new ones.
> +By default
> +.Nm
> +will whitelist the source of all inbound SMTP connections that are logged.
> +This option is needed if connections redirected to
> +.Xr spamd 8
> +are logged,
> +and no distinct
> +.Xr pflog 4
> +interface is configured for
> +.Nm .
>  .It Fl W Ar whiteexp
>  Adjust the time for
>  .Ar whiteexp
>  in hours.
>  The default is 864 hours (approximately 36 days); maximum is 2160 hours
>  (approximately 90 days).
>  .It Fl Y Ar synctarget
>  Add a target to receive synchronisation messages; see
> Index: spamlogd.c
> ===================================================================
> RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.c,v
> retrieving revision 1.21
> diff -u -d -p -8 -r1.21 spamlogd.c
> --- spamlogd.c     18 Mar 2011 22:37:06 -0000      1.21
> +++ spamlogd.c     7 Mar 2013 19:46:44 -0000
> @@ -63,29 +63,30 @@
>  int debug = 1;
>  int greylist = 1;
>  FILE *grey = NULL;
> > u_short sync_port;
>  int syncsend;
>  u_int8_t           flag_debug = 0;
>  u_int8_t           flag_inbound = 0;
> +u_int8_t           flag_updateonly = 0;
>  char                      *networkif = NULL;
>  char                      *pflogif = "pflog0";
>  char                       errbuf[PCAP_ERRBUF_SIZE];
>  pcap_t                    *hpcap = NULL;
>  struct syslog_data         sdata  = SYSLOG_DATA_INIT;
>  time_t                     whiteexp = WHITEEXP;
>  extern char               *__progname;
> > void logmsg(int , const char *, ...);
>  void      sighandler_close(int);
>  int       init_pcap(void);
>  void      logpkt_handler(u_char *, const struct pcap_pkthdr *, const u_char 
*);
> -int       dbupdate(char *, char *);
> +int       dbupdate(char *, char *, int);
>  void      usage(void);
> > void
>  logmsg(int pri, const char *msg, ...)
>  {
>    va_list ap;
>    va_start(ap, msg);
> > @@ -187,22 +188,22 @@ logpkt_handler(u_char *user, const struc
>                        sizeof(ipstraddr));
>    }
> > if (ipstraddr[0] != '\0') {
>            if (hdr->dir == PF_IN)
>                    logmsg(LOG_DEBUG,"inbound %s", ipstraddr);
> else > logmsg(LOG_DEBUG,"outbound %s", ipstraddr);
> -          dbupdate(PATH_SPAMD_DB, ipstraddr);
> +          dbupdate(PATH_SPAMD_DB, ipstraddr, hdr->dir == PF_IN);
>    }
>  }
> > int
> -dbupdate(char *dbname, char *ip)
> +dbupdate(char *dbname, char *ip, int inbound)
>  {
>    HASHINFO        hashinfo;
>    DBT             dbk, dbd;
>    DB              *db;
>    struct gdata    gd;
>    time_t          now;
>    int             r;
>    struct in_addr  ia;
> @@ -227,16 +228,20 @@ dbupdate(char *dbname, char *ip)
>    /* add or update whitelist entry */
>    r = db->get(db, &dbk, &dbd, 0);
>    if (r == -1) {
>            logmsg(LOG_NOTICE, "db->get failed (%m)");
>            goto bad;
>    }
> > if (r) {
> +          if (inbound && flag_updateonly) {
> +                  logmsg(LOG_DEBUG,"ignoring %s", ip);
> +                  goto bad;
> +          }
>            /* new entry */
>            memset(&gd, 0, sizeof(gd));
>            gd.first = now;
>            gd.bcount = 1;
>            gd.pass = now;
>            gd.expire = now + whiteexp;
>            memset(&dbk, 0, sizeof(dbk));
>            dbk.size = strlen(ip);
> @@ -280,17 +285,17 @@ dbupdate(char *dbname, char *ip)
>    db = NULL;
>    return (-1);
>  }
> > void
>  usage(void)
>  {
>    fprintf(stderr,
> -      "usage: %s [-DI] [-i interface] [-l pflog_interface] "
> +      "usage: %s [-DIU] [-i interface] [-l pflog_interface] "
>        "[-W whiteexp] [-Y synctarget]\n",
>        __progname);
>    exit(1);
>  }
> > int
>  main(int argc, char **argv)
>  {
> @@ -302,23 +307,26 @@ main(int argc, char **argv)
>    char *sync_iface = NULL;
>    char *sync_baddr = NULL;
>    const char *errstr;
> > if ((ent = getservbyname("spamd-sync", "udp")) == NULL)
>            errx(1, "Can't find service \"spamd-sync\" in /etc/services");
>    sync_port = ntohs(ent->s_port);
> > - while ((ch = getopt(argc, argv, "DIi:l:W:Y:")) != -1) {
> +  while ((ch = getopt(argc, argv, "DIUi:l:W:Y:")) != -1) {
>            switch (ch) {
>            case 'D':
>                    flag_debug = 1;
>                    break;
>            case 'I':
>                    flag_inbound = 1;
> +                  break;
> +          case 'U':
> +                  flag_updateonly = 1;
>                    break;
>            case 'i':
>                    networkif = optarg;
>                    break;
>            case 'l':
>                    pflogif = optarg;
>                    break;
>            case 'W':


Reply via email to