Monthly Archives: August 2009

SpamAssassin and Exim on Arch Linux: some config trouble

I had this happen – SA wasn’t reading user_prefs out of a proper home dir:

[12071] info: spamd: creating default_prefs: //.spamassassin/user_prefs
[12071] dbg: config: using "/.spamassassin" for user state dir
[12071] dbg: config: mkdir /.spamassassin failed: mkdir /.spamassassin: Permission denied at /usr/share/perl5/vendor_perl/Mail/ line 1577
[12071] dbg: config: Permission denied
[12071] warn: config: cannot write to //.spamassassin/user_prefs: No such file or directory
[12071] info: spamd: failed to create readable default_prefs: //.spamassassin/user_prefs
[12071] dbg: config: read_scoreonly_config: cannot open "//.spamassassin/user_prefs": No such file or directory

I thought this was due to the way spamassassin was invoked, so I tried specifying the user and homedir explicitly. It didn’t work. I tried creating a ‘spamd’ user, a homedir, changing the invocation to that:

sudo spamd -c --max-children 3 --username spamd -H "/var/lib/spamassassin/" -s stderr -D

Didn’t help.

Then I RTFMed some. That reminded me of writing something about user ‘nobody’ in exim.conf. That’s the user for which spam filtering is invoked; so if you allow per-user configuration, it doesn’t really matter that you specify “/var/lib/spamassassin” as a homedir, that’s just for the parent spamd process. For every child, the directory will be changed; for ‘nobody’ it’s ‘/’.

So I changed that line to have ‘spamd’ instead, and voila!

[12071] info: spamd: creating default_prefs: /var/lib/spamassassin/.spamassassin/user_prefs
[12071] dbg: config: using "/var/lib/spamassassin/.spamassassin" for user state dir
[12071] warn: config: created user preferences file: /var/lib/spamassassin/.spamassassin/user_prefs
[12071] dbg: conf: finish parsing

Tor on per-tab basis

I have just had this idea: since in fact reads the config file for every new tab (i.e. every new uzbl instance), it should be very easy to allow tor be enabled on a per-tab basis, something I wanted badly for Firefox. Nais!

Configuring Exim to use SpamAssassin in ArchLinux

There’s a lot of outdated stuff floating on the internets. This one was most useful to me.

Basically, if you install Exim and SA from pacman, you’ve already got everything enabled. Filtering spam is done via an Access Control List (the last one in exim.conf). Don’t bother with transports unless you’re sure you want them.

Add spamd to daemons in rc.conf. If you want reject logging, append

-s /var/log/spamd.log -D check

to the string in /etc/config.d/spamd. commands to FIFO

The list is on line 782 (ATM) of The FIFO location is determined by your settings (top of file for defaults, possibly overridden from config). It’s like this:

782     def parse_command(self, cmd):
783         '''Parse instructions from uzbl child processes.'''
785         # Commands ( [] = optional, {} = required )
786         # new [uri]
787         #   open new tab and head to optional uri.
788         # close [tab-num]
789         #   close current tab or close via tab id.
790         # next [n-tabs]
791         #   open next tab or n tabs down. Supports negative indexing.

So, to open a new tab in uzbl_tabbed from newsbeuter, you need a script like

echo "new $1" > `ls -1 /tmp/uzbltabbed_*`

Then call it from newsbeuter – put this in ~.newsbeuter/config:

browser "~/.local/share/uzbl/scripts/ %u"

Arch Linux: no sound from speakers, headphones OK

As noted here, you must tell the system that you’re using a laptop, so there are several outputs. Edit /etc/modprobe.d/50-sound.conf (or similar) like this:

alias snd-card-0 snd-hda-intel
alias sound-slot-0 snd-hda-intel

options snd-hda-intel model=hp

EDIT: for more models and options, see this Ubuntu Wiki page.

Lousy jailed-lighttpd scripts

Now, jailed has its own automated scripts to generate its own proper fully-contained jails (as far as “jails” on GNU/Linux go, that is; they’re chroots, actually).

The following scripts are leftovers from me trying to do the same, before finding out that the utilities are already there. They have been lying around for quite some time. I’m just copying them here so I can delete them from the home dir.



# Create a jail for lighttpd


mkdir -p $jail
cd $jail

mkdir tmp
chmod 1777 tmp

mkdir -p        var/log/lighttpd var/run/lighttpd home/http
chown http:http var/log/lighttpd var/run/lighttpd home/http
chmod a+rx      var/log/lighttpd var/run/lighttpd home/http

mkdir etc
cp -avr /etc/php etc/
cp -v /etc/hosts /etc/nsswitch.conf /etc/resolv.conf /etc/services /etc/localtime etc/
cp -v /etc/group /etc/host.conf /etc/passwd /etc/protocols etc/

mkdir -p usr/bin
cp /usr/bin/php /usr/bin/php-cgi usr/bin/

# read l2chroot before use
./l2chroot /usr/bin/php
./l2chroot /usr/bin/php-cgi

# just in case some permissions were forgotten...
chmod a+rx $jail




# general config
. /etc/rc.conf
. /etc/rc.d/functions

function jailcmd () {
su http -c "$*"

PID=`pidof -o %PPID /usr/sbin/lighttpd`

case "$1" in
stat_busy "Starting jailed lighttpd Daemon"
[ -z "$PID" ] && jk_chrootlaunch -j $jailroot -x /usr/sbin/lighttpd -- -f /etc/lighttpd/lighttpd.conf 2>&1
if [ $? -gt 0 ]; then
add_daemon lighttpd
stat_busy "Stopping jailed lighttpd Daemon"
[ ! -z "$PID" ] && jailcmd kill $PID &>/dev/null
if [ $? -gt 0 ]; then
rm_daemon lighttpd
rm -f $jailroot/var/run/lighttpd/
$0 stop
sleep 1
$0 start
echo "usage: $0 {start|stop|restart}"



# Use this script to copy shared (libs) files to Apache/Lighttpd chrooted
# jail server.
# ----------------------------------------------------------------------------
# Written by nixCraft <>
# (c) 2006 nixCraft under GNU GPL v2.0+
# + Added ld-linux support
# + Added error checking support
# ------------------------------------------------------------------------------
# See url for usage:
# -------------------------------------------------------------------------------
# Set CHROOT directory name

if [ $# -eq 0 ]; then
echo "Syntax : $0 /path/to/executable"
echo "Example: $0 /usr/bin/php5-cgi"
exit 1

[ ! $BASE ] && mkdir -p $BASE || :

# iggy ld-linux* file as it is not shared one
FILES="$(ldd $1 | awk '{ print $3 }' |egrep -v ^'\(')"

echo "Copying shared files/libs to $BASE..."
for i in $FILES
d="$(dirname $i)"
[ ! -d $BASE$d ] && mkdir -p $BASE$d || :
/bin/cp $i $BASE$d

# copy /lib/ld-linux* or /lib64/ld-linux* to $BASE/$sldlsubdir
# get ld-linux full file location
sldl="$(ldd $1 | grep 'ld-linux' | awk '{ print $1}')"
# now get sub-dir
sldlsubdir="$(dirname $sldl)"

if [ ! -f $BASE$sldl ];
echo "Copying $sldl $BASE$sldlsubdir..."
/bin/cp $sldl $BASE$sldlsubdir


There. Sorry for the tabbing, it went AWOL.

Erik Naggum’s ideas and principles

Some insightful short reading: