# Integrating DSPAM into Postfix/MySQL [SOLVED]

## NotExcessive

I'm trying to get DSPAM integrated with my Postfix/Dovecot/MySQL installation, which at this point is working fine. I've followed the instructions at http://gentoo-wiki.com/HOWTO_Spam_Filtering_with_DSPAM_and_Postfix but have now come unstuck. Starting /etc/init.d/dspam, I can see the process runs without any startup errors, but it doesn't do anything either. The system delivers mail exactly the same way as it did before I emerged DSPAM.

I've followed the wiki and the DSPAM documentation as best I can, but I'm now lost on this. The web interface works fine, just there's nothing going on for the web interface to tell me about.

I have Postfix/Dovecot set up with all virtual users and domains, delivering into maildirs at /vmail/domains/DOMAIN/USER and that all works fine. I created an alias for dspam at spam@mydomain.net and using PostfixAdmin created a maildir at /vmail/domains/mydomain.net/dspam. I'm not sure if dspam actually needs me to create its own maildir to receive mail on, but Postfix bounced mail for spam@mydomain.net if I didn't give it one. I thought by the instructions in .procmailrc (see below) that it would have a maildir under its home directory, and not have anything to do with the maildirs I use at /vmail/domains/DOMAIN/USER.

I placed .procmailrc in /var/spool/dspam:

```
LOGFILE=$HOME/procmail.log

VERBOSE=yes

LOGABSTRACT=all

MAILDIR=$HOME/.maildir

DEFAULT=$HOME/.maildir/
```

but I don't know how this is supposed to work at training dspam although I've read elsewhere that you do it anyway. I don't have procmail on the system, but read elsewhere that you include this file just as a formula.

I emerged maildrop as I understand I need some sort of agent to talk between dspam and Postfix.

My configuration files are as follow:

/etc/mail/dspam/dspam.conf:

```
Home /var/spool/dspam

StorageDriver /usr/lib/libmysql_drv.so

TrustedDeliveryAgent "/bin/maildrop"      # Maildrop

DeliveryHost        127.0.0.1

DeliveryPort        10025

DeliveryIdent       localhost

DeliveryProto       LMTP

OnFail error

Trust root

Trust mail

Trust mailnull 

Trust smmsp

Trust daemon

Trust filter

#Debug *

TrainingMode teft

TestConditionalTraining on

#Feature sbph

#Feature noise

Feature chained

Feature whitelist

#Algorithm chi-square

#Algorithm naive

Algorithm graham burton

#PValue robinson

#PValue markov

PValue graham

Preference "spamAction=quarantine"

Preference "signatureLocation=message"  # can be 'message' or 'headers'

Preference "showFactors=off" # changed from on

ServerPID /var/run/dspam/dspam.pid

ServerMode auto

ServerParameters        "--user filter --deliver=innocent"

ServerDomainSocketPath  "/var/run/dspam/dspam.sock" # socket to receive email from Postfix

AllowOverride trainingMode

AllowOverride spamAction spamSubject

AllowOverride statisticalSedation

AllowOverride enableBNR

AllowOverride enableWhitelist

AllowOverride signatureLocation

AllowOverride showFactors

AllowOverride optIn optOut

AllowOverride whitelistThreshold

#MySQLServer       /var/runlib/mysql/mysql.sock

MySQLServer       /var/run/mysqld/mysqld.sock

MySQLPort   3306

MySQLUser    dspam

MySQLPass       secret

MySQLDb         dspam

MySQLCompress   true

MySQLVirtualTable          postfix

MySQLVirtualUIDField       mailbox

MySQLVirtualUsernameField  username

MySQLUIDInSignature    on

LocalMX 127.0.0.1

SystemLog on

UserLog   on

Opt out

ProcessorBias on

## EOF

```

/etc/postfix/dspam_incoming:

```
FILTER dspam:unix:/var/run/dspam/dspam.sock
```

I've modified this line in /etc/postfix/main.cf:

```
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_relay_domains, check_recipient_access, pcre:/etc/postfix/dspam_incoming
```

/etc/postfix/master.cf:

```
dspam     unix  -       -       n       -       10      lmtp

127.0.0.1:10025 inet    n       -       n       -       -       smtpd

  -o smtpd_authorized_xforward_hosts=127.0.0.0/8

  -o smtpd_client_restrictions=

  -o smtpd_helo_restrictions=

  -o smtpd_sender_restrictions=

  -o smtpd_recipient_restrictions=permit_mynetworks,reject

  -o mynetworks=127.0.0.0/8

  -o receive_override_options=no_unknown_recipient_checks

```

Running netstat -tunlp shows me that the master process is listening on ports 10025 and 25:

```
> netstat -tunlp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name   

tcp        0      0 0.0.0.0:993             0.0.0.0:*               LISTEN      7722/dovecot        

tcp        0      0 127.0.0.1:10025         0.0.0.0:*               LISTEN      22543/master        

tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      25834/mysqld        

tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      7722/dovecot        

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      16266/apache2       

tcp        0      0 0.0.0.0:10000           0.0.0.0:*               LISTEN      6033/perl           

tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      22543/master        

tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      16266/apache2       

udp        0      0 0.0.0.0:10000           0.0.0.0:*                           6033/perl           

udp        0      0 127.0.0.1:123           0.0.0.0:*                           6014/ntpd           

udp        0      0 192.168.2.2:123         0.0.0.0:*                           6014/ntpd           

udp        0      0 0.0.0.0:123             0.0.0.0:*                           6014/ntpd    
```

There are no mbox or log files present under ~dspam (/var/spool/dspam).

So it's installed, but inert. I don't know where to go from here. Can anybody please advise?Last edited by NotExcessive on Thu Aug 24, 2006 12:19 pm; edited 1 time in total

----------

## .:chrome:.

use dspam as delivery agent, via the "mailbox_command" postfix parameter

----------

## NotExcessive

Added the line 

```
mailbox_command = /usr/bin/dspam --deliver=innocent --user $USER -- -d %
```

 to /etc/postfix/main.cf, but it's still the same. No mail goes missing though. Do I still need the directory /vmail/domains/mydomain/dspam?

----------

## magic919

Problem here:

```

/etc/postfix/dspam_incoming

/./     FILTER dspam:unix:/var/run/dspam/dspam.sock

```

You don't seem to have the all important /./ for it to match and thus trigger DSPAM.

----------

## NotExcessive

OK - did that, restarted everything. Mail behaves the same way, but now this time in the logs I see

```
Aug 19 20:07:13 [dspam] query error: Table 'dspam.postfix' doesn't exist: see sql.errors for more details

Aug 19 20:07:13 [dspam] Unable to open file for writing: /var/spool/dspam/log/sql.errors: Permission denied

```

Created a blank file /var/spool/dspam/sql.errors and chown'd it to dspam:dspam

Tried sending mail to myself from outside, no problem.

Tried sending mail to spam@mydomain.net, ends up in /vmail/domains/mydomain.net/dspam.

Shouldn't that have ended up in dspam's quarantine section? There's still no maildir under ~dspam.

----------

## magic919

Sending to outside should be business as usual as DSPAM does not get involved.

Sending to dspam@mydomain.net will just end up in the maildir.  You'd generally it up as a RE-training address - so it would run DSPAM and retrain the error.

Sending mail to yourself from outside.  When you say no problem do you mean DSPAM is doing its stuff?

----------

## NotExcessive

To make sure I haven't broken my existing system, I send myself an email from an external mail service like gmail and then return it back. 

After rebooting the machine and sending some test emails, there are no longer any errors in the log files from dspam. Everything is quiet.

I thought sending mail to spam@mydomain would tell dspam it's a spam mail and train it to ignore similar mails. Is this incorrect? If so, how do I set it to be a re-training process? I'm not sure how to do this from the documentation.

Also, if I stop dspam by /etc/init.d/dspam stop, shouldn't incoming mail also stop if dspam is in the loop but not running? I've done just that, yet when I send a mail to myself from gmail, it still ends up in my normal mailbox at /vmail/domains/mydomain/user.

----------

## magic919

The usual use for spam@ is to teach DSPAM about spam it let through in error.  Send it to spam@ and get it to be put through DSPAM

```

spam:      "|/usr/bin/dspam --process --class=spam --source=error --user filter"

```

This presumes your DSPAM is running as filter as per my Wiki article.

Stick this in your aliases file and run postalias against the file.

Regarding training DSPAM on what is spam.  I'd still say don't bother.  I generally leave Postfix wide open to accept all kinds of stuff sent its way and let it get on with it.  My current install here had no corpus training at all and is better than the (previous) one I trained.  YMMV.

I get an error when I stop DSPAM.   

```
connect to /var/run/dspam/dspam.sock[/var/run/dspam/dspam.sock]: No such file or directory
```

But Postfix just holds it in the deferred queue.

----------

## NotExcessive

I've added the line spam:      "|/usr/bin/dspam --process --class=spam --source=error --user filter"  to the bottom of /etc/mail/aliases, and run postalias aliases.

Restarting, I've noticed the change in behaviour:

If I send an email from gmail, it arrives at my mailbox within ~10 seconds, every time.

If I stop dspam, mail still arrives at my mailbox, but it now takes ~45 seconds, every time. 

This repeatable. When dspam is not running, there are no errors in /var/log/everything/current, yet the mail still arrives, although it's delayed. Surely the dspam system can't be running? Mail should get queued up as you said, right? So maybe the plumbing is wrong- dspam isn't inserted into the mail reception loop?

Also, I have "spam" aliased to "dspam@mydomain.net" in my Postfix virtual users table. This has /vmail/domains/mydomain/dspam as the maildir. I take it I need to delete all the virtual stuff relating to user dspam?

----------

## NotExcessive

Ah. Boo-boo. I've added the line you gave me to /etc/mail/aliases.

Should it go there, in /etc/postfix/aliases, or in the aliases table in MySQL? The reason I ask is because Postfix is set up for virtual users and I'm not sure if the unix-account type stuff is still relevant. I can't execute "newaliases" if it's the case of /etc/mail/aliases as that command isn't on the system. I think it's part of ssmtp but of course you can't have that on the system along with Postfix.

Seeing as how all the user accounts are virtual (no unix accounts used) is this setup still going to work OK?

Edit: I've removed the alias for dspam@mydomain.net from the postfix virtual users' table and a message sent to spam@mydomain.net has bounced as a result. Seems I have to get Postfix to use the aliases table /etc/postfix/aliases to do the redirection for dspam and still use my SQL table for the users?

I've also changed the following line in /etc/postfix/master.cf:

```
#dspam     unix  -       -       n       -       10      lmtp

dspam     unix  -       -       n       -       10      pipe
```

But no change. One other thing, as I said, I've emerged maildrop but do I need to do any configuration for it, or does it just run? And since I don't have any local transport and have set 

```
mailbox_command = /usr/bin/dspam --deliver=innocent --user $USER -- -d %
```

 then do I need to specify maildrop for anything anyway? Am I chasing a red herring here?

From what I can see, there are three things to check and sort out:

1) Make sure dspam is being inserted into the loop when mail comes in. Obviously it's not at the moment, because I can stop the daemon and mail still comes in, and I don't get any error messages.

2) Make sure dspam is sending mail on to the respective user accounts once we're sure it's playing man-in-the-middle.

3) Sort out the alias business so that mail to spam@mydomain.net ends up (where in the system?) being fed to dspam.

I forgot to mention earlier that I emerged dspam with the following flags:

```
USE="clamav daemon ldap mysql virtual-users -berkdb -cyrus -debug -large-domain -logrotate -oci8 -postgres -procmail -sqlite -sqlite3 -user-homedirs"
```

Help please! I'm about to strangle the cat.

----------

## magic919

1.  Sort out your logging and you'll see what Postfix logs when DSPAM is stopped.  There cannot be nothing in the logs.  Postfix would log the next hop failure.

2.  Forget maildrop.

3.  You've got the spam@ address working, can't you stop playing with it?   :Smile: 

Another option to consider when re-training missed spam (false negatives) is an IMAP folder.  I use these currently and run a script to check the content and re-train any found there as spam.

----------

## NotExcessive

I found it too hard going via the wiki and getting one service on 25 and another on 10025 - couldn't understand why dspam never got into the loop, so I changed my tack and decided to use maildrop. If I can break the plumbing and insert dspam between postfix and maildrop, that's easier for me to get my head around.

One thing with maildrop though is it gives me server-side sorting of mail into folders, so I suppose that's one thing I can't have if I just get dspam working. You really think I should give the dspam-direct approach another go?

----------

## magic919

I guess you'll go with what suits you.  However, without correct logging from Postfix you cannot know whether DSPAM was 'not working'.  I really strongly suggest you address that.  The maillog is the eyes and ears on my system.

These methods are certainly not mutually exclusive.  You can use DSPAM as a content filter and that's like on the wiki.  It's fine if you want just the one DSPAM username for all to use and want to avoid some permissions clashes.  You can do that and still use maildrop afterwards (provided you can settle it in your virtual mail set up).

DSPAM is great when it works and proves a challenge to get it going.  Most of us sweat along the way.

Maildrop is calling DSPAM direct.  I prefer the Postfix passing to DSPAM server approach.  Each to their own I guess.

Good luck.

Tony

----------

## NotExcessive

OK well I just got maildrop working successfully as a back-end to postfix - it's delivering mail properly now and I like the idea of being able to specify rules so that it can populate mailing list folders for me so that I don't have to bother setting up identical rules in multiple copies of Thunderbird.

Now I'll turn my attention to dspam. I'll change the mailbox_command in main.cf from 

```

mailbox_command = /usr/bin/maildrop -d  "$USER" "$LOCAL" "$DOMAIN"
```

 to 

```
mailbox_command = /usr/bin/dspam --deliver=innocent --user $USER -- -d %
```

 and have a go at getting dspam to work. 

I do have a couple of concerns though - the first is being able to pass the parameters from dspam or somewhere else to maildrop so that it knows which mailbox it's delivering to - don't want the same problem that I just solved a short while ago happening all over again. (https://forums.gentoo.org/viewtopic-t-490988-highlight-.html)

The second is the spam@ address thing again. Will I need to have a virtual user called "spam", or will mail sent there somehow find its way to dspam for its inspection? Will have to do some reading about that. Also, one thing I noticed about the cgi web interface from my installing dspam last week: when I set options away from the default (say like "Filter sensitivity during the training period"), I hit "submit changes" and then I notice that all the selected options pop back to default again. They're not "sticky." I'm not sure if that's just the page reloading and it doesn't read the settings (I've seen some apps like that - dumb thing) or the interface isn't really talking to dspam at all.

Will have to see when the time comes.

Hmmm another thing comes to my mind: if I use mailbox_command = /usr/bin/dspam --deliver=innocent --user $USER -- -d % to pump from postfix into dspam, what do I do about the current virtual_transport = maildrop  line I have in main.cf at the moment? Do I just comment anything to do with transport out of the main.cf file, because as far as postfix is concerned, once it's connected to dspam its responsibility for determining where the mail goes, ends?

----------

## magic919

Now you've got maildrop working you can leave it alone and just use it as a Postfix content filter.  You'll be undoing your good work otherwise.

I understand the uses of maildrop.  I don't go virtual and I have procmail doing the same thing here.

Why don't you consider getting maildrop to call DSPAM??  You are 3/4 of the way along that road after all.

The webgui is a liar!  I set all my preferences in the dspam.conf file directly.  The webgui didn't used to show the changes when I used it for that in the distant past.  I only use it to check it for accuracy.  Plus out of the last 3,800 messages it thought 3 of them were spam!

Tony

----------

## NotExcessive

I thought dspam was going to be the content filter? Maybe I have the terminology wrong. My idea was to have:

POSTFIX --> DSPAM --> MAILDROP------------->  USER MAILDIRs

Dspam was the content filter (after all we want to filter on what's in the email) and maildrop the final delivery agent. I was planning on putting some rules into maildrop so that mailing lists, for example, would be sorted into the user's mailing list folders, saving on having to put sorting rules in Thunderbird.

Now if I understand you right, you're suggesting:

POSTFIX -->  MAILDROP --> DSPAM ------------->  USER MAILDIRs

Now if that's correct, why bother having maildrop at all (apart from doing the mail sorting as I just mentioned), and more importantly, how does the mail get delivered to the maildirs after dspam has done its thing? I think I have no option but the first model as all domains and users on my system are purely virtual. I think I can live with dspam intercepting everyone's mail - after all if it's as good as people say it is, it'll only be a short-term inconvenience having everyone's false positives sharing the same quarantine and having the sysadmin (moi) check out the list and manually forward on the real emails. The learning should reduced that dramatically.

I'm still not sure about how to implement a spam@ address for retraining though. Will worry about that once I have the basics up and running I guess.

The web gui sounds like I'll have to watch out for quirks.

----------

## NotExcessive

OK now this is interesting. If I comment out the mailbox_command from main.cf, my maildrop stuff still works. All you need is virtual_transport=maildrop. The mailbox_command line doesn't even get used.

Hmmm moving right along....

I found out why there were no messages in the logs about dspam last week. Setting mailbox_command = /usr/bin/dspam --deliver=innocent --user $USER -- -d % and doing a few tests, I saw that mail was still being delivered with dspam turned off. That's because I although I had commented out virtual_transport=virtual and virtual_transport=maildrop, I saw it had reverted to using Postfix's virtual by default. So dspam wasn't even getting a look in. Aaaarggh.

If I set virtual_transport=dspam, and mailbox_command = /usr/bin/dspam --deliver=innocent --user $USER -- -d %, the logs tell me that the process is throttling, just when it's about to go into the pipe.

This is what I have in /etc/postifx/main.cf:

```
virtual_transport = dspam

mailbox_command = /usr/bin/dspam --deliver=innocent --user $USER -- -d %
```

Where do I go from here?

----------

## magic919

The usual routing is Postfix >> Content Filter >> Postfix >> Delivery.  This is Postfix's idea of a content filter.

Why have maildrop?  Use it is an email-sorter by all means.  However some people use it to trigger DSPAM, instead of as a content filter with Postfix.  Maildrop would just pipe it through DSPAM and then get it handed back by DSPAM (unless quarantined...) to maildrop for sorting/delivery.  Some get DSPAM to mark rather than grap the email and so the user has a Spam folder instead of a quarantine.  Get the picture?

You will NOT get many false positives in my experience.  9000 messages and 35 false is the worst system I have.

Sounds like you are getting it under control.

Tony

----------

## NotExcessive

In that case I'll have a go at the wiki again where that port 10025 business is being used to re-inject the mail into postfix after dspam has done its thing. I'm not sure how it all works - as I said dspam never appeared in the loop that first time, and I'm sure having everything virtual makes some of what's in the wiki not applicable, but I'll give it a try.

I may have a lot of questions for you though so be prepared!

First thing is how I make sure dspam actually gets into the loop - as I said I had problems with the virtual_transport bypassing it.

----------

## magic919

You probably need to understand a bit more about Postfix.  It's made up of many separate processes and the mail traverses these.  

A key point is that the wiki method syphons off the mail and hands it off to the content filter at the QMGR stage.  This is before the mail hits LOCAL or VIRTUAL delivery.  So whether you have local users or virtual users the content filter/DSPAM bit gets done and then re-injected into Postfix BEFORE the stage where it matters about virtual and local delivery.

```

POSTFIX  >> sends via LMTP to

                        vv

                      DSPAM via SMTP to

POSTFIX port 10025  <<

       vv

LOCAL or VIRTUAL

    DELIVERY

```

Some of your 'problems' were caused by monkeying with LOCAL delivery and you had VIRTUAL users.  This would be ineffectual by definition.

Hope this helps.

I'll expect more questions  :Smile: 

----------

## NotExcessive

Seeing as how you're expecting questions, it would grieve me to disappoint you, so here goes:

I've gone through the wiki again and inserted dspam into the loop. It actually fired, so we're finally on the right track. From the logs I can see that the trigger function is indeed working:

```
Aug 22 09:39:28 [postfix/smtpd] connect from nf-out-0910.google.com[64.233.182.191]

Aug 22 09:39:29 [postfix/smtpd] NOQUEUE: filter: RCPT from nf-out-0910.google.com[64.233.182.191]: <me@mydomain.net>: Recipient address triggers FILTER dspam:unix:/var/run/dspam/dspam.sock; from=<me@gmail.com> to=<me@mydomain.net> proto=ESMTP helo=<nf-out-0910.google.com>

Aug 22 09:39:29 [postfix/smtpd] D7248B68B: client=nf-out-0910.google.com[64.233.182.191]

Aug 22 09:39:30 [postfix/cleanup] D7248B68B: message-id=<a4bae7570608211639i61c659b0u718036b71bcfe3a7@mail.gmail.com>

Aug 22 09:39:30 [postfix/qmgr] D7248B68B: from=<me@gmail.com>, size=1631, nrcpt=1 (queue active)

Aug 22 09:39:30 [dspam] query error: Table 'dspam.postfix' doesn't exist: see sql.errors for more details

                - Last output repeated 2 times -

Aug 22 09:39:30 [dspam] bailing on error -2

Aug 22 09:39:30 [dspam] received invalid result (! DSR_ISSPAM || DSR_INNOCENT) : -2

Aug 22 09:39:30 [dspam] query error: Table 'dspam.postfix' doesn't exist: see sql.errors for more details

Aug 22 09:39:30 [dspam] process_message returned error -2.  delivering.

Aug 22 09:39:30 [postfix/smtpd] auxpropfunc error invalid parameter supplied_

Aug 22 09:39:30 [postfix/smtpd] warning: numeric hostname: 192.168.2.2

Aug 22 09:39:30 [postfix/smtpd] connect from unknown[127.0.0.1]

Aug 22 09:39:30 [dspam] Invalid data waiting for code 250: 402 Error: command not implemented_

```

Now although the config part of dspam created a database called "dspam", there's nothing anywhere about a table called 'dspam.postfix', and sql.errors is empty.

What's it asking for?

----------

## NotExcessive

OK, getting farther down the track. I've added this to dspam.conf so it can hit the MySQL database:

```
MySQLServer       /var/run/mysqld/mysqld.sock

MySQLPort

MySQLUser      dspam

MySQLPass      secret

MySQLDb         dspam

MySQLCompress       true
```

Stopping postfix, restarting dspam, and starting postfix again, I send my self a totally blank email from gmail. This is what I see in the logs:

```
Aug 22 10:43:02 [postfix/smtpd] connect from nf-out-0910.google.com[64.233.182.187]

Aug 22 10:43:03 [postfix/smtpd] NOQUEUE: filter: RCPT from nf-out-0910.google.com[64.233.182.187]: <me@mydomain.net>: Recipient address triggers FILTER dspam:unix:/var/run/dspam/dspam.sock; from=<me@gmail.com> to=<me@mydomain.net> proto=ESMTP helo=<nf-out-0910.google.com>

Aug 22 10:43:03 [postfix/smtpd] AE6461FBA8: client=nf-out-0910.google.com[64.233.182.187]

Aug 22 10:43:04 [postfix/cleanup] AE6461FBA8: message-id=<a4bae7570608211743j1050281dl7649de89f4277c75@mail.gmail.com>

Aug 22 10:43:04 [postfix/qmgr] AE6461FBA8: from=<me@gmail.com>, size=1637, nrcpt=1 (queue active)

Aug 22 10:43:04 [postfix/smtpd] auxpropfunc error invalid parameter supplied_

Aug 22 10:43:04 [postfix/smtpd] warning: numeric hostname: 192.168.2.2

Aug 22 10:43:04 [postfix/smtpd] connect from unknown[127.0.0.1]

Aug 22 10:43:04 [postfix/smtpd] BDF29230CA: client=unknown[127.0.0.1]

Aug 22 10:43:04 [postfix/cleanup] BDF29230CA: message-id=<a4bae7570608211743j1050281dl7649de89f4277c75@mail.gmail.com>

Aug 22 10:43:04 [postfix/qmgr] BDF29230CA: from=<me@gmail.com>, size=2081, nrcpt=1 (queue active)

Aug 22 10:43:04 [postfix/smtpd] disconnect from unknown[127.0.0.1]

Aug 22 10:43:04 [postfix/lmtp] AE6461FBA8: to=<me@mydomain.net>, relay=/var/run/dspam/dspam.sock[/var/run/dspam/dspam.sock], delay=1, status=sent (250 2.6.0 <me@mydomain.net> Message accepted for delivery)

Aug 22 10:43:04 [postfix/qmgr] AE6461FBA8: removed

Aug 22 10:43:04 [authdaemond] Authenticated: sysusername=<null>, sysuserid=5000, sysgroupid=5000, homedir=/vmail/domains/, address=me@mydomain.net, fullname=<null>, maildir=mydomain.net/me/, quota=<null>, options=<null>

Aug 22 10:43:04 [authdaemond] Authenticated: clearpasswd=password, passwd=<null>

Aug 22 10:43:04 [postfix/pipe] BDF29230CA: to=<me@mydomain.net>, relay=maildrop, delay=0, status=sent (mydomain.net)

Aug 22 10:43:04 [postfix/qmgr] BDF29230CA: removed

```

And I receive the email, with the sole line !DSPAM:44ea53b2130948010175730!  in it.

In the log above, dspam is quiet, but I can see the hand-off via lmtp and then authdaemond wakes up so I take it dspam is indeed active and scanning emails now.

So.... by the line in the received email, I take it that dspam has looked at it, inserted a tag (I suppose I should set signatures to "headers" instead so it doesn't intrude on the message body, yes?) and passed it on.

Now if that's true, the only thing I need to do is set up the retraining side of things. Am I correct in presuming that I have to create a virtual user with maildir /vmail/domains/mydomain/dspam, create an alias in postfixadmin that points spam@mydomain.net to dspam@mydomain.net, and place this retraining .procmail thingy (technical talk) somewhere in this maildir and let dspam know where to find it? 

I can't use 

```
spam:      "|/usr/bin/dspam --process --class=spam --source=error --user filter" 
```

 in /etc/postfix/aliases as everything is virtual, and I can't create an alias in the virtual user table of the same thing as it isn't a valid user, so that's why I'm saying is the only option to create an actual virtual user.

One more thing: I compiled postfix and everything else mail-related with the maildir flag alone. I've noticed there's no mailbox under ~dspam at all, so is it a case of dspam will create one as soon as a quarantine event occurs, or will it use the virtual maildir, or what? As it is now, will it dump any quarantines into hyperspace and lose them?

Oh by the way the web gui is now "sticky" although I haven't recompiled it or anything. Probably because dspam is running without errors?

----------

## NotExcessive

Whoaaa! Tony, I need your help!

This thing being all-virtual is causing me some problems regarding the retraining thing. I can't use aliases to pipe into dspam (unless I've missed something) so I thought I'd be clever and use maildrop to cheat for me.

I've created the virtual user dspam@mydomain.net, and created an alias, spam@mydomain.net. There is a maildir at /vmail/domains/mydomain.net/dspam. I know you said that for retraining you use the mechanism 

```
"|/usr/bin/dspam --process --class=spam --source=error --user filter"
```

 to pipe the email into dspam.

What I did was to create this maildroprc file:

```
#

# File: /etc/maildrop/maildroprc

# Global maildrop filter

#

# set path and shell

#

PATH=/bin:/usr/bin:/usr/local/bin

SHELL=/bin/sh 

# set verbose level for debugging

VERBOSE=9

logfile "/var/log/maildrop.log"

# DSPAM retraining redirection

if ( /dspam@mydomain.net/ )

{

    `| /usr/bin/dspam --process --class=spam --source=error --user filter`

}

```

The idea being that instead of using aliases directly, mail intended for dspam@mydomain.net would be grabbed by maildrop and piped into dspam.

I thought this was a bloody clever workaround, except that it doesn't work. Mail intended for dspam@mydomain.net just goes straight into /vmail/domains/mydomain.net/dspam/new.

Bugger.

Is it my syntax is wrong and it ignores the command, is it that you can't connect the output of maildrop to a pipe, or is there something else wrong with this approach?

----------

## magic919

Maybe you are thinking too hard.  Why have IF x=1 then DSPAM.  Set up your maildrop recipe to stick ALL mail for spam@ through DSPAM to re-train.  There won't be anything else going there.

----------

## NotExcessive

I've discovered more about the syntax for maildrop and now have it set as

```
if ( /spam@/ )

{

    xfilter "/usr/bin/dspam --process --class=spam --source=error --user filter"

    log '*** DSPAM RETRAINING ***'

}

```

However I now get the error

```
Aug 23 11:21:25 [dspam] Unable to determine the runtime user

Aug 23 11:21:25 [maildrop] Unable to filter message.

Aug 23 11:21:25 [postfix/pipe] E6F611B72FD: to=<dspam@mydomain.net>, orig_to=<spam@mydomain.net>, relay=maildrop, delay=1, status=deferred (temporary failure. Command output: 7314: [08/23/2006 11:21:25] Unable to determine the runtime user /usr/bin/maildrop: Unable to filter message. )
```

So it looks like dspam doesn't quite know what to make of maildrop here. Any remedies?

----------

## NotExcessive

I nuked virtual mail user 'dspam' and created instead 'filter', and created the virtual maildirs too. emails sent to spam@mydomain get aliased to filter@mydomain.

Just re-emerged dspam with the following flags, just in case it didn't happen right the first time:

```
USE="clamav daemon mysql -ldap virtual-users -berkdb -cyrus debug -large-domain logrotate"
```

and now, sending an email to spam@mydomain,  I get 

```

Aug 23 16:15:30 [maildrop] Unable to filter message.

Aug 23 16:15:30 [postfix/pipe] 69A631B87CE: to=<filter@mydomain.net>, orig_to=<spam@mydomain.net>, relay=maildrop, delay=0, status=deferred (temporary failure. Command output: sh: /usr/bin/dspam: Permission denied /usr/bin/maildrop: Unable to filter message. )
```

So now the problem has shifted from being unable to determine the run-time user to one of permissions. I supppose it's an improvement...

Added execute permissions by all to /usr/bin/dspam. Now we're back to the run-time user error again.

Sigh.

----------

## magic919

Hmmm.

Maildrop is a funny thing.  If I remember rightly it has some ideas about trusted users and stuff, a bit like DSPAM.

You seem to be so close to getting this finished and yet...

On the topic of aliases, Postfix etc.  If you have filter as a 'real' user and given that you haven't switched off local delivery can't you just use a plain alias?  If you have switched off local then can you make the re-train command an alias for spam@.  You seems to have this working earlier in the thread.

My only other thought would be a dedicated transport for mail spam@ but that's a bit of a sledgehammer to crack a nut.

Ah, the joys of training by using an IMAP folder and a cron job  :Smile: 

Tony

----------

## NotExcessive

Problem is, if filter isn't in the virtual users' table, postfix barfs at it. This is what I have in my postfix main.cf file:

```
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf

virtual_transport = maildrop

local_transport = local

maildrop_destination_recipient_limit = 1
```

As a fully-virtual mail server, it works great. I don't know how to run both virtual and real apart from those above lines. If I can run both types at the same time, what do I do about "filter" as a real user? If it knows to use local for filter and virtual/maildrop for everybody else, then I suppose the problem goes away, because the whole headbanging thing here is simply trying to implement piping the retraining email into dspam.

----------

## magic919

Why do you think local delivery is off?  Make filter a local user and send it a message.

----------

## NotExcessive

What I did was pull 'filter' out of all the postfixadmin entries so that nothing related to user 'filter' was left in the virtual postfix setup. 

I then created an alias of filter: | /usr/bin/dspam --process --class=spam --source=error --user filter in /etc/mail/aliases, ran postalias on that file, and restarted.

If I send it a message via Thunderbird from my machine or gmail from outside, it comes back complaining about user 'filter' not being in the virtual alias table. To be expected as it's not in the virtual postfix systgem any more.

Sending a message from the console results in:

```
mailx filter

test

asda

sd

asd

/.

mailx: /usr/sbin/sendmail: No such file or directory

Can't send mail: sendmail process failed with error code 1

```

Postfix won't work down here even though I have

```
local_transport = local

virtual_transport = maildrop
```

-don't know why.

So what do I do? Configure something to act as a transport so I can send filter a message from the command line? But even if I do that, how does that help me? If I forward emails from Thunderbird to spam@, it's going to be coming in via the virtual table system.

PS: I tried making an alias in postfixadmin for spam@mydomain to go to filter@localhost but postfixadmin spat the dummy about the destination address.

----------

## magic919

Have you created a user called filter?

----------

## NotExcessive

There is a real user called filter, I can log on as filter from the command line, it has a home directory and also a public_html one that the cgi interface from dspam is running on.

To be honest though I think the best bet is to get the permissions business between maildrop and dspam sorted out. Then everything stays virtual and it's easier to manage - don't know if I'm that keen to start tinkering with a working virtual system by trying to integrate unix accounts and then somehow have to make the virtual system pass mail to a local account for just one address. I dunno - the more it gets into catering for local accounts, the farther it drifts from my original system, which works a treat and I don't want to break it!

Surely there has to be a way of getting maildrop to pipe into dspam with the routine I have in my maildroprc file.

----------

## magic919

Sticking with your virtual approach (and I admire the purity of approach) will mean rolling up your sleeves.  I think you'll have to manipulate the MySQL tables directly if Postfixadmin won't play.  Looks like the virtual_alias_maps table from here.

----------

## NotExcessive

I think that's what it comes to. Posfixadmin won't let you enter anything that isn't on its list of domains, so I know that somewhere in there I'm going to have to kludge it to pipe into dspam, if I can't get the maildroprc thing happening.

I'll still try for that though - after all it triggers on "spam@" and passes it to the retraining command, or would, if only I can sort out the permissions problem. I think that's more elegant than taking a chainsaw to the MySQL postfix tables.

This is where I'm currently at with the maildroprc method when I forward to spam@ from Thunderbird:

```
Aug 24 00:18:36 [postfix/smtpd] 0C7141B8AD3: client=unknown[127.0.0.1], sasl_method=PLAIN, sasl_username=dean@mydomain.net

Aug 24 00:18:36 [postfix/cleanup] 0C7141B8AD3: message-id=<44EC63BB.6040303@mydomain.net>

Aug 24 00:18:36 [postfix/qmgr] 0C7141B8AD3: from=<dean@mydomain.net>, size=1281, nrcpt=1 (queue active)

Aug 24 00:18:36 [postfix/smtpd] disconnect from unknown[127.0.0.1]

Aug 24 00:18:36 [authdaemond] Authenticated: sysusername=<null>, sysuserid=5000, sysgroupid=5000, homedir=/vmail/domains/, address=spam@mydomain.net, fullname=<null>, maildir=mydomain.net/spam/, quota=<null>, options=<null>

Aug 24 00:18:36 [authdaemond] Authenticated: clearpasswd=secret, passwd=<null>

Aug 24 00:18:36 [maildrop] Unable to filter message.

Aug 24 00:18:36 [postfix/pipe] 0C7141B8AD3: to=<spam@mydomain.net>, relay=maildrop, delay=0, status=deferred (temporary failure. Command output: sh: /usr/bin/dspam: Permission denied /usr/bin/maildrop: Unable to filter message. )

```

If I remove the filter rule it goes straight into the mydomain.net/spam/ maildir, so it's just the permissions problem  when trying to shove it into dspam instead. Why does this have to be so bloody hard? Why do I have to be a purist? Why does a mouse squeak when you hit it with a 10kg sledge hammer?

I think I'll go and do something nasty to the cat now and tackle this problem a little later - for now I've lost the wood for the trees.

Don't leave the country - there will be MORE questions later!

----------

## magic919

Here's an idea.  Let it delivery the email for now, sure.  Why not just run a script that runs as a cronjob.  It'll re-train anything it find in that folder as spam.  That's the easiest method I can think of.

All of my users have a folder called Spam.  They stick it in there and I run a cron to search and re-train on any read messages found therein.

cronjob

```

0,15,30,45 * * * * /usr/sbin/dspam_retrain.sh -d=/home -u=filter -s=Spam -i=false -v > /dev/null 2>&1

```

Script

```

#!/usr/bin/perl

#

# Train DSPAM from imap folders

# Norman Maurer <nm@byteaction.de> or <nm@spam-box.de>

##################################################

use Getopt::Mixed;

Getopt::Mixed::getOptions("d:s h v u:s s:s i:s user>u domain-dir>d spam-dir>s innocent-dir>i help>h verbose>v");

my $spam_dir = $opt_s;

my $innocent_dir = $opt_i;

my $domain_dir = $opt_d;

my $user = $opt_u;

my $spam_opts = "--class=spam --source=error";

my $innocent_opts = "--class=innocent --source=error";

my $spam_count = 0;

my $innocent_count = 0;

&help if (defined $opt_h || !defined $opt_u || !defined $opt_s || !defined $opt_i || !defined $opt_d);

&train_spam;

&train_innocent;

exit 0;

sub help

{

        print "\nUsage:\n";

        print "-d\t--domain-dir\tdirecotry where the domains are keept.\n";

        print "-u\t--user\tuser which should use for train dspam.\n";

        print "-s\t--spam-dir\tname of the directory where the users store their missing spam\n";

        print "-i\t--innocent-dir\tname of the firectory where the users store their false positives\n";

        print "-v\t--verbose\tgive verbose output\n";

        print "-h\t--help\tshow this help\n";

        print "\n";

        print "Example:\n";

        print "$0 -d=/var/qmail/vpopmail/domains -u=byteaction.de -s=spam-missing -i=false-positive -v\n\n";

        exit 0;

}

sub train_spam

{

        my @spam_array = split(/\n/, `find $domain_dir -regex '.*\.$spam_dir/cur/.*'`);

        foreach my $spam (@spam_array)

        {

                system("dspam $spam_opts --user $opt_u --client < $spam");

                system("rm -f $spam");

                $spam_count++;

        }

        if (defined $opt_v)

        {

                print "$0: Trained $spam_count missed spams\n";

        }

}

sub train_innocent

{

        my @innocent_array = split(/\n/, `find $domain_dir -regex '.*\.$innocent_dir/cur/.*'`);

        foreach my $innocent (@innocent_array)

        {

                system("dspam $innocent_opts --user $opt_u --client < $innocent");

                system("rm -f $innocent");

                $innocent_count++;

        }

        if (defined $opt_v)

        {

                print "$0: Trained $innocent_count false positives\n";

        }

}

```

Just needs Perl and one Perl module.  Or you could adapt it.  Script is just something I found.  Spelling errors and typo's not mine  :Smile: 

----------

## NotExcessive

Thanks - I'll have to study this as I don't know anything about perl. Over here, a perl is a plastic thing that takes AA batteries and then you switch it on and err.. umm... never mind.

You're currently using this script? I take it each user has two extra folders, "spam" and "false positive". So this script recurses all the folders and builds up its knowledge from the sum total? Or is there only one "spam" and one "false positive" folder for the entire system?

Also, with this method, do you have to leave the folders full or can you empty them out at some stage? Am I correct in saying that you have to set dspam to operate in tagging mode (send to user with SPAM marked on it) rather than in quarantine mode, otherwise they don't have anything to put into the "false positive" folder?

Sorry if the questions are a bit naive but as I said I don't know anything about perl so off we go to study new and wonderous things.

----------

## magic919

I use this on my systems.  Users have a folder (one each usually) called Spam.  They have no false positive folder as they don't get any  :Wink: 

You pass the names of the folders etc to the script in the cron job. -s=Spam -i=false -d=/home  Mine recurses from /home .

It trains any read messages it finds, one by one, and deletes them.

As mine quarantines there are no false positives.

One or two of my systems the Spam folder is shared but has the same effect.

DSPAM looks up the message ID and re-trains itself until satified it could spot that as spam in the future.

Hope this helps.

Tony

----------

## NotExcessive

OK thanks very much - I'll have a look at this tomorrow and see if I can get it going. I'll come back to you with the results.

----------

## NotExcessive

OK, I compiled the perl module, created a 'spam' folder and ran the script. Didn't complain, so I added a cron job.

To do a bit of testing, I forwarded some spam from my old system (which didn't have any spam filtering) via my ISP relay so that it would come back in and be scanned. I then moved it from the inbox to the spam folder. The cron job ran a couple of minutes later, the spam folder emptied, and looking at the stats table I saw that the 'innocent learned' count had gone down by one, and the 'spam learned' count had gone up by one.

I resent the same email. It ended up in my mailbox. Moved it to 'spam'. Waited. Folder emptied. Resent the same email again. It never made it to the inbox. Looking at ~dpam/data/local/filter/filter.mbox, I saw the email inside, about three times I think.

Looks like it works.

Now a question as to the behaviour of the web interface. Although the mbox had something in it, the interface always shows empty. Stats 0, quarantine empty, although the Preferences tab works and updates the preferences table. Is this supposed to be? I know I haven't received any genuine spam yet (the domain boxes are too new) but I would have thought the fact that mbox had something in it would show up in the quarantine tab. Or is it that because I've put those messages into the spam folder and hence told dspam they're junk, it puts them in the mbox but doesn't show them up in the quarantine tab, because that's only for when incoming mail gets tagged as spam by the program and not by me?

----------

## magic919

Sounds good.  Usually it's permissions problems.  mbox is in /var/spool/dspam/data/local/filter/ make sure filter ownership/permissions from there down.

Off this topic a bit.  Did you get the virtual users authenticating against MySQL using Dovecot in the end?  And what Dovecot version?

----------

## NotExcessive

By "sounds good" I take it you're saying that everything is as it should be and my assumptions about what will show up on the interface are correct? Just to make sure I did a chown -R filter:users /filter.

Yes, having the authentication against MySQL with Dovecot runs smooth as.

Bit tricky getting to grips with it at first, but once you know how it's done.... maildrop had me going for a while because I didn't know you had to use courier-authlib to do the authentication so that was more reading!

This is the list of packages I've used to pull this virtual mail server together:

mail-mta/postfix-2.2.10

www-apps/postfixadmin-2.1.0

dev-db/mysql-4.1.21

net-www/apache-2.0.58-r2 

mail-filter/maildrop-2.0.1 

net-mail/dovecot-1.0_beta8 

mail-filter/dspam-3.6.6 

www-apps/dspam-web-3.6.4 

dev-lang/php-5.1.4-r6

dev-lang/perl-5.8.8-r2 

dev-perl/Getopt-Mixed-1.008

net-libs/courier-authlib-0.58 

mail-client/squirrelmail-1.4.8 (very snazzy - I like)

I already knew how to set up apache, php, and MySQL; done that plenty of times, but you know, looking at the list of things I've had to install and figure out to get working... hell, I scared myself. I'm still a bit pissed that I couldn't get the maildroprc filter rule for retraining dspam running - that would have been neat. However I can happily live with the IMAP folder/CRON job approach.

Anyway the end result of a week's work is that I now have a working virtual mail server I can access anywhere in the world - thanks for everybody's help, and you Tony for the dspam side of things - intuitive, it AIN'T. The only thing left is to make sure dspam is doing its thing (time will tell on that) and I still have to figure out how to send on port 465 from Thunderbird so that sending mail from outside on the laptop is secure as receiving it. Also a few nigglies to work out with maildrop (it seems to ignore my .mailfiter file) but that's not critical.

----------

## magic919

Well just so you don't think this is a one-way thing.  On my newer Gentoo server I now have a full virtual email set-up.  I migrated it from local to virtual over the last few days.

Postfix

Postfixadmin

Dovecot

Squirrelmail

DSPAM & ClamAV

with LAMP set-up (MySQL5)

Thought I'd best give one a go.

One hiccup.  Dovecot just would not accept my config updates.  Then I found that it wasn't stopping when I restarted the daemon.  Was fine once I'd sussed that.

Maybe I'll look at TLS and SASL over the weekend  :Smile: 

Tony

----------

## NotExcessive

If you get secure SMTP running over port 465 from outside, let me know how you did it   :Very Happy: 

----------

## NotExcessive

Hey one more question about dspam: after I chown'd the folder /filter to filter:user like you said, I tested the system out by sending spam from outside. Although the stats table updated, nothing ever got put into /data/local/filter/filter.mbox. It stayed at 0 bytes.

When I restored the original chown (mail:root) on filter.mbox and sent another spam in, then it wrote to the file successfully, and upon examining the contents of filter.mbox, there was the spam I just sent. So I'm going to go back to chown -R mail:root /filter to go back to the system as it was when it was installed.

However the quarantine tab in the web gui still showed empty. This has to be wrong as there is now an entry in filter.mbox.

What permissions are on your mbox files, and does your gui work properly?

After looking into the config in /filter/cgi-bin/conf.pl, I see references that if you run cgi as untrusted, auto-detect of the file system doesn't work. I think that might be what's wrong with the gui - it can't "talk" to mbox. What setup do you have there?

----------

## magic919

This rings a bell.  I think I'll stick by my ownership suggestion but I seem to remember opening permissions wide to get it to work.  Never bothered bringing permissions back down.

Mine:

```

drwxrwx---  2 filter users    312 Aug 24 16:25 .

drwxrwxrwx  4 dspam  dspam    120 May 31 03:54 ..

-rw-rw----  1 filter users     11 May 31 00:35 filter.firstrun

-rw-rw----  1 root   users     11 May 31 02:04 filter.firstspam

-rw-rw----  1 filter users 710536 Aug 24 17:21 filter.log

-rw-rw----  1 filter users      0 Aug 24 15:29 filter.mbox

-rw-------  1 filter users      1 Aug 24 16:25 filter.mbox.size

-rw-rw----  1 filter users      0 Aug 24 16:25 filter.mbox.stamp

-rw-------  1 filter users      8 May 31 02:03 filter.rstats

-rw-rw----  1 filter users     21 Aug 24 17:21 filter.stats

```

Gui works fine.  Stats, quarantine, analysis etc.

Tony

----------

## NotExcessive

Ah. In that case, I still have a problem. I only have three of your files there;

filter.mbox, filter.stats, and filter.log, but they all seem to have the right stuff in them so I'll have to conclude everything is working correctly except for the web interface.

I knew this wasn't going to end so easily.

You didn't have to make any changes to your cgi stuff at all?

----------

## magic919

You don't have to worry about firstrun and firstspam as you may not even have notifications in use.

Mbox and its colleagues form an ensemble.  Once you have an mbox you'll probably get the other 2.

CGI stuff was all as per the wiki as far as I recall.  As I said just before I did open up permissions (777?) to get it all to work.  Never bothered cranking them down again.

You might want to make filter an admin to match my set-up.  In the admins file in cgi-bin.

----------

## NotExcessive

I added filter as an admin but noticed no difference apart from the nice extra "admin" tab. As for setting everything to 777 in /cgi-bin, it died a horrible death - Internal Server Error and that's all she wrote. Going back to 755 made the interface come up again.

Go figure.

Here's one clue though: when I click on the administrative tab (using either root or filter as user beforehand) I get the following error at http://localhost/~filter/cgi-bin/admin.cgi:

```
An Error Has Occured

The following error occured while trying to process your request:

Unable to open logfile: Permission denied

If this problem persists, please contact your administrator.
```

I've done a chmod 666 on the three filter.* files anyway, just in case it proves to be needed later.

Guessing here.     :Confused: 

----------

## NotExcessive

OK, I've finally cracked it - we now have a fully singing-and-dancing graphical dspam system.    :Shocked: 

What I had to do was go into user manager and make "filter" a member of:user, dspam, mail, root.

Don't know if these are all necessary as I checked them all at once, but hey it works now and I ain't gonna fiddle with it.

One other thing: although this now made the user interface come alive with data, when I sent it more spam and had it catch the spam on the next round, filter.mbox didn't increase in size. I reset the permissions for filter.mbox to 660 from 666 and voila! filter.mbox had a message added to it, "quarantine" showed an extra item, and everything now works like a dream.

Christ this is fiddly stuff - the innocent act (that's my plea, judge) of giving filter.mbox extra permissions makes it all fall over. Setting everything to 777 in /cgi-bin makes it all fall over. Do you see where I'm going with this?

Nice to know some things are still a black art.

I'll list my chowns and chmods below, in case it helps someone in the future.

BTW "filter" has UID:1000 and GUID:100 and in the listing here, filter.mbox is 0 bytes because I just emptied it via the GUI.

/var/spool/dspam/data/local/filter:

```
drwxrwx--- 2 mail   root    208 Aug 25 12:32 .

drwxrwx--- 3 root   root     72 Aug 22 10:43 ..

-rw-rw---- 1 mail   root  57656 Aug 25 12:38 filter.log

-rw-rw---- 1 mail   root      0 Aug 25 12:42 filter.mbox

-rw------- 1 filter users     1 Aug 25 12:42 filter.mbox.size

-rw------- 1 filter users     9 Aug 25 12:26 filter.rstats

-rw-rw---- 1 mail   root     13 Aug 25 12:38 filter.stats
```

/home/filter/public_html/cgi-bin:

```
drwxr-xr-x 3 filter users   440 Aug 25 08:40 .

drwxr-xr-x 5 filter users   120 Aug 25 08:07 ..

-rwxr-xr-x 1 filter users 17937 Aug 25 08:07 Makefile

-rwxr-xr-x 1 filter users   583 Aug 25 08:07 Makefile.am

-rwxr-xr-x 1 filter users 18124 Aug 25 08:07 Makefile.in

-rwxr-xr-x 1 filter users 22705 Aug 25 08:07 admin.cgi

-rwxr-xr-x 1 filter users  3390 Aug 25 08:07 admingraph.cgi

-rwxr-xr-x 1 filter users    12 Aug 25 08:15 admins

-rwxr-xr-x 1 filter users  2392 Aug 25 08:40 configure.pl

-rwxr-xr-x 1 filter users  2388 Aug 25 08:07 configure.pl.in

-rwxr-xr-x 1 filter users  1383 Aug 25 08:07 default.prefs

-rwxr-xr-x 1 filter users 39608 Aug 25 08:35 dspam.cgi

-rwxr-xr-x 1 filter users  2881 Aug 25 08:07 graph.cgi

-rwxr-xr-x 1 filter users 17168 Aug 25 08:07 rgb.txt

drwxr-xr-x 2 filter users   640 Aug 25 08:07 templates
```

Thank you ball girls, thank you ball boys.

 :Very Happy: 

----------

## NotExcessive

TONY!!!!

Just when you thought it was safe to go back into the water, there is ONE thing more.

https://forums.gentoo.org/viewtopic-p-3532824.html#3532824

As they say in the movies, every time I try to get out, they reach out and pull me back IN!

----------

