Saturday, May 24, 2014

How to compile & install rmilter + clamav under Debian Wheezy

Rmilter is a milter-daemon by the same author of Rspamd. You can use it to integrate clamav (Anti Virus) scanning for your emails on postfix, and you will also need it if you want to integrate postfix with Rspamd itself. Click here for the compile & install how to of Rspamd under Debian Wheezy.

Even though it offers DCC and SPF integration, the Author clearly recommends not to enable those features as they are unsupported. SPF integration can be achieved with Rspamd and is also the preferred way.

So in this how to I will write down how you can compile rmilter on your Debian Wheezy server, add ClamAV (Anti-Virus) scanning and integrate it with postfix.

Prerequisites


# apt-get install \
cmake \
make \
gcc \
pkg-config \
libssl-dev \
bison \
flex \
libpcre3-dev \
libmilter-dev

Compile


# cd /usr/src
# wget https://github.com/vstakhov/rmilter/archive/1.6.1.tar.gz 
# tar xvfz 1.6.1.tar.gz
# cd rmilter-1.6.1/
# cmake \
-DMANDIR=/usr/share/man .
# make
# make install

Post Installation


# adduser \
--system \
--group \
--home /run/rmilter \
--no-create-home \
--disabled-login \
--gecos "rmilter" \
--force-badname \
_rmilter

# cp debian/rmilter.init /etc/init.d/rmilter
# nano /etc/init.d/rmilter

(change following line):
chown $USER:adm $RUNDIR 

(to):
chown $USER: $RUNDIR

# chmod 755 /etc/init.d/rmilter
# update-rc.d rmilter defaults

# nano /etc/rmilter.conf (replace all)

pidfile = /run/rmilter.pid;
bind_socket = inet:10033@127.0.0.1; # we need to bind to TCP, so postfix can access it in chroot
tempdir = /tmp;
max_size = 50M;
whitelist = postmaster, abuse;

Start


# /etc/init.d/rmilter start

Basically we only want to use rmilter for Anti-Virus scanning and Rspamd integration. Which is why we can keep the config very simple as stated above.

Next thing is to install clamav and integrate with rmilter.

ClamAV Installation


# apt-get install clamav clamav-daemon

Configuration


rmilter will put items to scan in the /tmp folder. Unfortunately they will only be accessible by the _rmilter user, so we will have to modify clamav that it can access those.

# nano /etc/clamav/clamd.conf

LocalSocketGroup _rmilter
User _rmilter

# nano /etc/clamav/freshclam.conf

DatabaseOwner _rmilter

# chown -R _rmilter: /var/log/clamav/ /var/run/clamav/ /var/lib/clamav/
# freshclam
# /etc/init.d/clamav-freshclam restart 
# /etc/init.d/clamav-daemon restart



Rmilter Integration



# nano /etc/rmilter.conf (add)

clamav {
        servers = /var/run/clamav/clamd.ctl;
        connect_timeout = 1s;
        port_timeout = 4s;
        results_timeout = 30s;
        error_time = 10;
        dead_time = 300;
        maxerrors = 10;
};

# /etc/init.d/rmilter restart


Postfix Integration


# nano /etc/postfix/main.cf 
smtpd_milters = inet:127.0.0.1:10033
milter_mail_macros =  i {mail_addr} {client_addr} {client_name}
milter_protocol = 4
milter_rcpt_macros = i {rcpt_addr}
milter_default_action = accept

# /etc/init.d/postfix restart


Always check your logs to see if something is not working!

Friday, May 23, 2014

How to compile & install unbound under Debian Wheezy

Unbound is a non-authoritative DNS Server (aka. recursor, resolver, etc.). It has a small memory footprint but can scale up for large traffic. Unbound should be definitely preferred over bind.

Many sysadmins actually underrate the importance of a good working DNS-Resolver - even though there is not much in the internet that happens without a dns-query prior. Hostname checks, mailserver DNSBLs, cURL, etc... Lets say you have a PHP script that fetches the twitter-feed via cURL or file_get_contents - if your DNS-Resolver is slow, alone the dns-query itself will take more time than the actually HTTP-GET.

I have seen many servers configured with 4.2.2.1 or even worse 208.67.220.220 (opendns) - if you want to use a public DNS, at least use Google's DNS: 8.8.8.8 / 8.8.4.4

If you run your own mailserver, you will most likely have to run your own local DNS-Resolver for two reasons:
  1. Speed (even though Google DNS are fast, you will want to save on additional ms)
  2. Blocks. Usually RBL/DNSBL block IPs that perform too many lookups - most public DNS-Resolver are affected by that.
Here are the steps to get unbound on your Debian Wheezy server up and running.

Prerequisites


# apt-get install \
make \
gcc \
libssl-dev \
libevent-dev \
libexpat1-dev

Compile


# cd /usr/src
# wget http://www.unbound.net/downloads/unbound-1.4.22.tar.gz 
# tar xvfz unbound-1.4.22.tar.gz
# cd unbound-1.4.22
# ./configure \
--prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--with-conf-file=/var/unbound/unbound.conf \
--with-ssl \
--with-libevent
# make && make install

Post-Installation


# adduser \
--no-create-home \
--system \
--group \
--home /var/unbound \
--disabled-login \
--gecos "Unbound DNS Resolver" \
--force-badname \
unbound

# nano /etc/init.d/unbound

ubound.init


# chmod 755 /etc/init.d/unbound
# update-rc.d unbound defaults

# nano /etc/default/unbound 
 
unbound.default

# cd /var/unbound
# wget ftp://FTP.INTERNIC.NET/domain/named.cache
# chown -R unbound: /var/unbound

# nano /var/unbound/unbound.conf

unbound.conf

Start


# /etc/init.d/unbound start


As stated in the unbound.conf, it will only listen to localhost. I highly suggest not to run a public dns unless you at least secure your self against DNS-Amplification Attacks (see here: http://dnsamplificationattacks.blogspot.com/).

Modify your /etc/resolv.conf with the unbound server and enjoy :)

Thursday, May 22, 2014

How to compile & install Rspamd (+ webgui) under Debian Wheezy

Rspamd is a relative new Anti-Spam daemon which works well with Postfix, Exim and Sendmail. It competes with the well established SpamAssassin, though claiming to be faster as it is written in C and uses LUA for some of its modules.

In this post I will only show how to successfully compile Rspamd under Debian Wheezy and how you can enable the webgui/web-interface with the help of Lighttpd.

I might add a posting in the future which will include the configuration of it.

Prerequisites


# apt-get install \
cmake \
make \
gcc \
libevent-dev \
libglib2.0-dev \
libgmime-2.6-dev \
liblua5.1-0-dev \
libssl-dev

Compile


# cd /usr/src
# wget https://github.com/vstakhov/rspamd/archive/0.6.9.tar.gz 
# tar xvfz 0.6.9.tar.gz
# cd rspamd-0.6.9/
# cmake \
-DCMAKE_INSTALL_PREFIX:PATH=/usr \
-DCONFDIR=/etc/rspamd \
-DDBDIR=/var/lib/rspamd \
-DRUNDIR=/run/rspamd \
-DLOGDIR=/var/log/rspamd .
# make
# make install

Post Installation


# adduser \
--system \
--group \
--home /var/lib/rspamd \
--disabled-login \
--gecos "rspamd spam filtering system" \
--force-badname \
_rspamd

# mkdir /run/rspamd
# mkdir /var/log/rspamd
# chown _rspamd: /run/rspamd/ /var/log/rspamd/

# cp debian/rspamd.init /etc/init.d/rspamd
# cp debian/rspamd.logrotate /etc/logrotate.d/rspamd
# chmod 755 /etc/init.d/rspamd
# update-rc.d rspamd defaults

modify the init-script for our installation

# nano /etc/init.d/rspamd

(search for mkdir -m 755 _rspamd:_rspamd -p /run/rspamd and comment-out)
# mkdir -m 755 _rspamd:_rspamd -p /run/rspamd


Web Interface


Install Lighttpd (not covered in this howto)

# nano /etc/lighttpd/vhost-rspam.conf

$HTTP["url"] == "/rspam" {
  url.redirect = ( "^/rspam$" => "/rspam/" )
  url.redirect-code = 301
}

alias.url += ( "/rspam/" => "/var/www/rspam-interface/" )

$HTTP["url"] =~ "^/rspamd/" {
  proxy.server  = ( "" => (
    ( "host" => "127.0.0.1",
      "port" => 81
    )
  ))
}

$SERVER["socket"] == "127.0.0.1:81" {
  url.rewrite-once = ( "^/rspamd/(.*)$" => "/$1" )
  proxy.server  = ( "" => (
    ( "host" => "127.0.0.1",
      "port" => 11336
    )
  ))
}

we can not use the latest git, as it already includes API-changes that will only go live with the 0.7 version of Rspamd.

# cd /var/www
# wget https://github.com/vstakhov/rspamd-interface/archive/f52166c8bbb9f68a1f9512861b344718d73f33e3.zip 
# unzip f52166c8bbb9f68a1f9512861b344718d73f33e3.zip
# mv rspamd-interface-f52166c8bbb9f68a1f9512861b344718d73f33e3/ rspam-interface/

set a "secure" password, though I'd highly recommend to additionally secure Lighttpd (SSL + mod_auth + non-default urls)

# nano /etc/rspamd/workers.conf

worker {
    type = "webui";
    count = 1;
    bind_socket = "127.0.0.1:11336";
    password = "PseudoSecurePassword";
}


Start


# /etc/init.d/rspamd start



Now point your browser to http://yourserver/rspam and use "127.0.0.1" as hostname and "PseudoSecurePassword" as password.

Sunday, May 4, 2014

Passwords, CPAN module to store passwords in a secure and simple way

I fucked up on my last post, so I decided to invest some time and do it right (or at least "try harder"). Basically when it comes to security, a developer should have access to a straight forward API to hash and verify passwords (for example on a login system).

It should be a no-brainer to implement and include somewhat back-and-forward-compatibility (e.g. do I really want to change my sub-calls from md5 to sha1 just after realizing the other is more secure?)

So I decided (analog to PHPs movement) to release a package called simply: "Passwords". It resides on its own root-namespace and there will never be any sub-modules on that namespace - to 100% avoid confusion.

The module is not a class/object to really simplify the API calls. Fell free to ask me questions or issue a Bug (after all its just the first version, so even though I tested it, it surely won't be perfect yet). The source code is available on Github.
 

Install


cpan Passwords

Use


use Passwords;

# will automatically generate a secure salt,
# and currently use the bcrypt algo
my $hash = password_hash('perlhipster');

# verify plaintext against the hash
if (password_verify('perlhipster', $hash)) {
    say 'password matches';
}


Props go to

Saturday, May 3, 2014

Stop Forum Spam with Perl

Comment Spam, Bot Registration and Forum Spam are all known issues when running a website. It is nearly impossible to manually moderate and block such activity. Some forums add CAPTCHAs, but not only are most of them breakable (think: Mechanical Turk), they are quite annoying to users.
If you think you can outsmart a spammer by manually blocking his IP, I guarantee you will give up fast, realizing spammers have a nearly unlimited supply of IP addresses.

But there is another solution that works very reliable: StopForumSpam.
They provide a list of IPs, Usernames and Email Addresses that are used by spammers (either recently or in the past). With that it is easy to implement an auto-moderation for your Forum, Blog or Comment system.

It is the de-facto standard Anti-Spam solution for PHP Applications/Forums (e.g. phpBB, vBulletin, etc.), fortunately they provide a free-to-use API so I decided to create a CPAN module for it in Perl.

Install


$ cpan WWW::StopForumSpam 

Use


#!/usr/bin/perl -w

use 5.010;
use strict;
use warnings;
use autodie;
use WWW::StopForumSpam;

my $sfs = WWW::StopForumSpam->new;

say $sfs->check(
    ip => '213.160.147.165',
    email => 'lightsoul@gmail.com',
    # username => "Devin", # optional, not recommended
);

# alternatively you can do a DNSBL based lookup (might be faster)
say $sfs->dns_check(
    ip => '213.160.147.165',
    email => 'lightsoul@gmail.com',
); 


Please check the official documentation for options available on the constructor (like timeout) - also you will only need an API-Key if you want to report spam.

You can have a look at the source code (and make suggestions) on Github, as well as Report Bugs there.


Also have a look at sfs.dnsbl.st for more information on using StopForumSpam via a DNS-Lookup (RBL/DNSBL).

Monday, April 28, 2014

Password hashing and verifying in Perl

*Update* I fucked up, read the updated Blog-Post

There seems still to be some misconceptions on how to securely store (e.g. DB) a password Perl. Let me break this down to you:

  • sha1 is not safe
  • md5 is even less safer
  • generating your own salt is brave, but useless

But nothing beats plaintext, which is whats going down in Legacy-Town. I therefor highly recommend the usage of "Authen::Passphrase::BlowfishCrypt":

  • uses BCRYPT which is de-facto standard
  • can automatically generate a random salt (which is much safer than all your pseudo random implementations)
  • you can supply "cost" which will cause more iterations in the hashing

To make the usage really straight forward (similar to PHPs password), I created a simple Perl Library (or in other words some functions).
Of course this is all meaningless if you transport the hash via HTTP (cookie) or store it in your webroot under "users.txt" or let your users chose insecure passwords.

Install the required PerlModule


$ cpan Authen::Passphrase::BlowfishCrypt

Download the password.pl




Sample File (foo.pl)


#!/usr/bin/perl -w -T -I./

use strict;
use warnings;

require "password.pl";

my $hash = password_hash("hello");
print $hash . "\n";

if (password_verify("hello", $hash)) {
    print "ok\n";
} else {
    print "nok\n";
}

Run


$ perl -T foo.pl 
{CRYPT}$2a$14$Jnex8RC7UK4REyU.RuxAcuGXpjM1QBdmXYL8YpcKscgdXT8fMbE9i
ok