Transparent SMTP proxy using WCCP

Why?

When you are in the wholesale ISP business you are having a lot of different users on the network which you cant control. Now we'd like to reduce the amount of spam the machines might sent out in case beeing compromised and used as an SMTP drone. Shutting down individual users or forcing them to use a specific relay is not an option.

Implementation

In my case i was using a Cisco 7206VXR with a 12.3B image. I had to add the following to the configuration:

ip wccp web-cache redirect-list 150 ip wccp 0 redirect-list 150 ip wccp 1 redirect-list 150 interface GigabitEthernet0/1 [...] ip wccp 0 redirect out ip wccp 1 redirect out [...] access-list 150 permit tcp any any eq smtp access-list 150 permit tcp any eq smtp any

WCCP uses a slightly modified GRE tunnel to pass on the packets to the proxy. For this the proxy has to announce itself to the WCCP router and the router will automatically set up a GRE tunnel. I used the python wccp2 implementation which can be found at http://anna.sgu.ru/svn/wccpd/wccpd/ to announce myself to the wccp router. I had to slightly modify the wccpd to actually announce redirecting port 25.

--- wccpd.py 2005-06-09 14:08:20.000000000 +0200 +++ ../wccpd.py 2005-05-27 15:52:21.000000000 +0200 @@ -41,7 +42,9 @@ WW.addService(TService(MyIP, Routers)) W = TService(MyIP, Routers) - W.setService(True, 0, 1, 6, 0x12, [ 81, 82, 3128, 8000, 8001, 8002, 8010, 8080 ]) + #W.setService(True, 0, 1, 6, 0x12, [ 81, 82, 3128, 8000, 8001, 8002, 8010, 8080 ]) + #def setService(self, type, id, priority = 0, protocol = 0, flags = 0, ports = []): + W.setService(True, 0, 1, 6, 0x12, [ 25 ]) WW.addService(W) while 1:

Now you'll get GRE encapsulated traffic sent toward the machine you configured in the wccpd.py to be the recipient. For this you will need to set up a tunnel on your machine. I am using Linux so i set up the tunnel like this:

ip tunnel add wccp0 mode gre remote wccp-router local my-ipaddr ip addr add 127.0.0.2 dev wccp0 ip link set wccp0 up iptables -t nat -A PREROUTING -i wccp0 -p tcp --dport 25 -j LOG iptables -t nat -A PREROUTING -i wccp0 -p tcp --dport 25 -j DNAT --to my-ipaddr:2525 echo 0 >/proc/sys/net/ipv4/conf/all/rp_filter echo 0 >/proc/sys/net/ipv4/conf/default/rp_filter echo 1 > /proc/sys/net/ipv4/ip_forward

You set up a tunnel, add an ip address and set the link to up. Then you add a DNAT entry to force all packets for port 25 to be redirected to your smtp-proxy running on port 2525. As the routing is obviously a little strange you'll need to disable return-path validation in the kernel and turn on forwarding.

As the smtp proxy for evaluation purposis i was using ProxSMTP 1.2.1 available at http://memberwebs.com/nielsen/software/proxsmtp/. The only thing i changed was the proxsmtp listen address in the configuration.

Problems

SMTP proxying by WCCP causes the SMTP session to originate from a different IP address. This itself should not be a problem but it will cause the SMTP to fail in case the user if forced to use DRAC or better POP before SMTP because the POP and SMTP session will originate from different IP addresses.