Postfix

Typically, users of mail clients (such as Thunderbird and Outlook) require a remote SMTP server in order to be able to send mail (often called simply an ‘outgoing mail server’ by the mail clients). Mail Transport Agents (such as postfix) include information about this initial hop from the user’s home computer to the relaying SMTP server in the “Received” headers it adds to the outgoing message. In particular, the user’s home IP address is included with every email they send.

Many users might consider this a breach of their privacy, since significant information can be gleened from one’s home IP address.

How to do this in Postfix

This anonymizes the first Received: header that comes from a client who SASL authenticates before sending mail.

Typically, if you authenticate and then send a message out through postfix, the following type of header, complete with identifying information added (the home DSL IP):

Received: from pond (adsl-79-259-53-135.dsl.some.place.net [79.259.53.135])
        (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
        (No client certificate requested)
        by mail.riseup.net (Postfix) with ESMTP id 5128CA2CA6 

If you use web mail, it is sent without this extra unnecessary information:

Received: from localhost (127.0.0.1)
        (SquirrelMail authenticated user micah)
        by mail.riseup.net with HTTP;
        Wed, 9 Feb 2005 11:24:51 -0800 (PST) 

This simple configuration to postfix anonymizes the first header into this:

Received: from localhost (localhost [127.0.0.1])
        (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
        (No client certificate requested)
        by mail.riseup.net (Postfix) with ESMTP id 5128CA2CA6 

getting your postfix anonymized

UPDATED: December 22, 2012 – alternative using smtp_header_checks and pcre
UPDATED: December 2, 2009 – newer regexp that does newlines properly in the header, credit and thanks to Paul Lesniewski!
UPDATED: Jan 24, 2008 – As of postfix 2.5, RFC3848 additional transmission types are now supported (ESMTPA, ESMTPS and ESMTPSA)

We used to maintain a set of patches that you could apply to the Postfix source to do this, but starting with Postfix 2.3 and newer there is the option that makes this much easier. You need to enable “smtpd_sasl_authenticated_heade r = yes”, which adds SASL information to your header. Once this information is there, header_checks can be put into place that rewrite the headers to anonymize their content.

The regular expression needs to be on one line, with a newline between the expression and the REPLACE line. Also, you will need to change the (auk.riseup.net) in the regexp below:

/^Received: from (.* \([-._[:alnum:]]+ \[[.[:digit:]]{7,15}\]\)).*?([[:space:]]+).*\(Authenticated sender: ([^)]+)\).*by (auk\.riseup\.net) \(([^)]+)\) with (E?SMTPS?A?) id ([A-F[:digit:]]+).*/
  REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])$2(Authenticated sender: $3)${2}with $6 id $7

This will replace the SASL authenticated hostname with ‘localhost’ and the resulting header will look like this:

Received: from [127.0.0.1] (localhost [127.0.0.1])   (Authenticated sender: micah@auk.riseup.net) with ESMTP id 17E6C86A for <micah@riseup.net>;   Sun, 12 Nov 2006 16:54:56 -0800 (PST)

NOTE: Be careful if you decide to use this regexp, you will need to replace $HOSTNAME, $DOMAIN and $TLD to match your system. Also, becareful if you change this regexp, some clients present different headers, I’ve seen some people have different information sent as ‘helo’ and not all say where the message is for.

UPDATE 2012 — You can save yourself a headache by using smtp_header_checks and PCRE:

# apt-get install postfix-pcre
# grep smtp_header_checks /etc/postfix/main.cf
smtp_header_checks = pcre:/etc/postfix/maps/smtp_header_checks.pcre
# cat /etc/postfix/maps/smtp_header_checks.pcre
/^\s*(Received: from)[^\n]*(.*)/ REPLACE $1 [127.0.0.1] (localhost [127.0.0.1])$2
/^\s*User-Agent/        IGNORE
/^\s*X-Enigmail/        IGNORE
/^\s*X-Mailer/          IGNORE
/^\s*X-Originating-IP/  IGNORE

The above solution present a handful of advantages over the previous one:
– the regular expression is much simpler
– it only modifies headers on outgoing mail, so you still get the normal Received path for incoming emails if you’re using it on the MX
– it also removes information about what mail client (MUA) you’re using, and other headers that might identify your IP or your MUA.

NOTE2: Be even more careful, this header replacement works great, but it logs that the replacement has been done, which means that you are storing this information, unless you are anonymizing your logs (see our syslog-ng section for more information about this), an example log for a header replacement:

Aug 11 10:12:00 mail postfix/cleanup[9204]: 1F6C52B2403: replace: header Received: from [192.168.1.1] (adsl-11-22-33-44.dsl.somenet.net [11.22.33.44])??(Authenticated sender: jose@example.com)??by mail.example.com (Postfix) with ESMTP id 1F6C from adsl-11-22-33-44.dsl.somenet.net[11.22.33.44]; from=<jose@example.com> to=<maria@example.com> proto=ESMTP helo=<[192.168.1.1]>: Received: from [127.0.0.1] (localhost [127.0.0.1])??(Authenticated sender: jose@examplecom)??with ESMTP id 1F6C52B2403

If you are not anonymizing your logs, you will capture the IP address as above, this is a bad thing!

Thanks to Paul Lesniewski for the updated regexp, and the additional poke about the important bit about the logs! Thanks to Martin Krafft for this new information

Exim

Typically, users of mail clients (such as Thunderbird and Outlook) require a remote SMTP server in order to be able to send mail (often called simply an ‘outgoing mail server’ by the mail clients). Mail Transport Agents (such as exim) include information about this initial hop from the user’s home computer to the relaying SMTP server in the “Received” headers it adds to the outgoing message. In particular, the user’s home IP address is included with every email they send.

Many users might consider this a breach of their privacy, since significant information can be gleened from one’s home IP address.

getting your exim anonymized

There are a few ways to do this:

Run a stunnel for the first hop

If you run a stunnel on the mail-server on Port 2525 pointing to port 25 on localhost and told users to send emails
over port 2525 to anonymize their ips. As for exim (or any MTA) the stunnel connects from localhost the first received from header automatically got localhost as sending ip.

However this has some issues: you have to use a special port and we wanted to protect users by default (so also on port 25, 587 and 465). Also it had the side effect that the helo message of the connecting MUA was still included and for example thunderbird is sending its local ip as helo message, which means that either a local ip or even the connecting ip (if directly attached to the internet) was still included.

Change the received_header_text configuration

If you apply the following configuration, you can anonymize ips of authenticated users. This may be the easiest method, simply change this configuration variable:

received_header_text = Received: \
                        ${if def:sender_rcvhost {from ${if def:authenticated_id \
                        {127.0.0.1 (helo=localhost.localdomain)} \
                        {$sender_rcvhost }}\n\t}}\
                        by $primary_hostname \
                        ${if def:received_protocol {with $received_protocol}} \
                        ${if def:tls_cipher {($tls_cipher)\n\t}}\
                        (Exim $version_number)\n\t\
                        id $message_id\
                        ${if def:received_for {\n\tfor $received_for}}

This effectively means that if email is received with authenticated and secure smtp then use a header of "Received: from $primary_hostname by $primary_hostname ", otherwise use the default.

Qmail

Typically, users of mail clients (such as Thunderbird and Outlook) require a remote SMTP server in order to be able to send mail (often called simply an ‘outgoing mail server’ by the mail clients). Mail Transport Agents (such as qmail) include information about this initial hop from the user’s home computer to the relaying SMTP server in the “Received” headers it adds to the outgoing message. In particular, the user’s home IP address is included with every email they send.

Many users might consider this a breach of their privacy, since significant information can be gleened from one’s home IP address.

getting your qmail anonymized

get the software

There is a software package called qmail-removeip, it is a small filter for use with qmail-qfilter, that strips some traces of private computers from certain incoming mails on a smarthost.

patch your qmail

There is another way that this can be done, the following patch, created by Erdgeist from CCC, when applied will do the anonymization that you need:

--- qmail-smtpd.c	2009-07-21 23:32:27.000000000 +0200
+++ qmail-smtpd.c	2009-07-21 23:30:48.000000000 +0200
bc. -34,7 +34,7 @@
 unsigned int databytes = 0;
 int timeout = 1200;
 unsigned int spfbehavior = 0;
-
+static int authd = 0;
 const char *protocol = "SMTP";
 
 #ifdef TLS
bc. -614,7 +614,10 @@
   qp = qmail_qp(&qqt);
   out("354 go ahead\r\n");
  
-  received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo);
+  if(!authd)
+    received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo);
+  else
+    received(&qqt,protocol,local,remoteinfo,local,0,local);
   spfreceived();
   blast(&hops);
   hops = (hops >= MAXHOPS);
bc. -839,7 +842,6 @@
 char **childargs;
 substdio ssup;
 char upbuf[128];
-int authd = 0;
 
 int authgetl(void) {
   int i;