Saturday, March 22, 2014

Cisco ASA with WCCP redirect to Squid proxy


Getting traffic redirection\interception from my ASA to my Squid proxy caused me a significant amount of pain! There's a great deal of blog posts out there on how to achieve this transparent redirect, but all are just a little different. I'm sure a seasoned Linux guy would have gotten this all done much quicker..but that was not the case for me! There's so many nuances and variants of Linux, and different ways to do the same thing, it makes a single clear cut procedure unlikely.

Anyway....the reasoning to setup a transparent proxy at all is little cloudy. It would have been much easier to point my client browsers to the the Squid box, and be done with it. If you're a windows shop, and use AD and Group Policy- then this is easy! But who wants to take the easy route? )

Squid proxy is pretty cool...plus it's free and easy to install, and well documented on line. I also paired my Squid box with Squid guard, for content and url filtering- again free.

Here are the main article I used as a guide to install and setup Squid with Squid Guard. Thanks to the author at dancourses!


To start, I used CentOS 6.5 for my proxy OS....with a minimal desktop install option- I like to have some gui for Linux. I used the latest Squid build at the time- 3.4.x. My ASA is a 5520 running 8.4.2 version software. I'll also assume you have experience editing linux config files- the metheod is up to you...if you're a cool terminal-only guy, and want to use VI for everything, by all means- I like Webmin and GEdit myself!

Once you have Squid and Squid Guard up and working a  conventional proxy - browsers pointing to the IP of the Squid box on port 3128...and want to setup a transparent redirect using Cisco's Web Cache Communication Protocol like I did, then read on.

My lab network is shown below- running in GNS3 - which is an amazing piece of software and essential for anybody in the networking field looking to gain knowledge or to simulate an environment for testing.


Obviously, ensure you have connectivity throughout your network and to the internet- we'll start with the ASA first.

Define the proxy server(s) that can register as a WCCP cache engine on the ASA , permit the subnets you want to be redirected, and deny your proxy server from being redirected.

access-list wccp-server extended permit ip host 192.168.1.19 any
access-list wccp-server remark Proxy servers that can register to WCCP

access-list wccp-traffic extended deny ip host 192.168.1.19 any
access-list wccp-traffic extended permit tcp 192.168.1.0 255.255.255.0 any eq www
access-list wccp-traffic extended permit tcp 192.168.1.0 255.255.255.0 any eq https
access-list wccp-traffic extended permit tcp 192.168.10.0 255.255.255.0 any eq www
access-list wccp-traffic extended permit tcp 192.168.10.0 255.255.255.0 any eq https
access-list wccp-traffic extended deny ip any any
access-list wccp-traffic remark Exclude proxy server from redirection- ID redirected subnets\clients

Next, tie in the WCCP config with the access lists you just created, and define the redirect interface, which would be your inside interface. Note that the proxy box and the clients must sit behind the same interface for this to work, per Cisco.

wccp web-cache redirect-list wccp-traffic group-list wccp-server

wccp interface inside web-cache redirect in

The other caveat with this is the WCCP Router ID....the ASA will pick the highest numbered IP to use as it's WCCP ID...this will be the source IP for the directed GRE packets coming from your ASA to your Squid proxy. So...it's probably best to design your IP scheme with this in mind...or else you'll have to ensure you have routes to any other interfaces that might be your WCCP ID. Mine is the inside interface at 192.168.10.5.

Next up- the squid.conf file....found in /etc/squid

I added these right at the end of the file. Note the intercept port- we'll use another port for that- 3129, and keep the stock 3128 port for normal proxying. Also, there's your WCCP Router ID IP.


# Intercept mode
http_port 3129 intercept

# WCCP Router IP- Inside ASA
wccp2_router 192.168.10.5

# forwarding
wccp2_forwarding_method gre

# GRE return method gre
wccp2_return_method gre

# standard web cache, no auth
wccp2_service standard 0


Now, restart Squid: service squid restart and it should register with the ASA.

On the ASA, do a show wccp and you should see that it has a cache engine (your squid box) registered.



Now for the OS adjustments on the Squid\CentOS box. I created a script called ifup-local in /sbin. In CentOS, this file is called when any interface is brought up. So just make it executable, and it will be fired up at system boot.

#!/bin/bash

# Setup and bring up the wccp\gre interface

modprobe ip_gre
ip tunnel add wccp0 mode gre remote 192.168.10.5 local 192.168.1.19 dev eth0
ifconfig wccp0 192.168.1.19 netmask 255.255.255.255 up


# disable rp_filter, or the packets will be silently discarded

echo 0 >/proc/sys/net/ipv4/conf/wccp0/rp_filter
echo 0 >/proc/sys/net/ipv4/conf/eth0/rp_filter

# enable ip-forwarding and redirect packets to squid

echo 1 >/proc/sys/net/ipv4/ip_forward

# catch the gre encapsulated http traffic-decapsulate it, and send it to Squid on port 3129

iptables -t nat -A PREROUTING -i wccp0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.19:3129

At this point, restart you Squid server. And go to a client browser...and hit the internet. The ASA should be catching your http requests, packing them up into GRE packets, and sending them to Squid. CentOS will encapsulate them, send them to Squid on port 3129. and then proxy the client requests as normal. And if you have Squid Guard, or another filtering application, you should be blocking content as well...won't that make your users happy!?

Here's a screen shot of a Wire Shark capture taken at eth0 of the Squid server when requesting a web site. The first TCP SYN packet is high lighted. You can see the GRE encapsulated header from the ASA there, with the request from the client to the web site server. The rest that follows set up the communication between the web site and the client with more SYNs and ACKs...then the actual HTTP GETs, requesting the content.



That's it! It is simple enough - just took me time to get the right config on the Linux side- the iptables command at the end, with the DNAT directive did it for me. The REDIRECT directive you may see on other blogs, did not work...it wasn't decapsulating the packets.


Additional reference for the Squid Wikis: