Some assumptions:

1) You are using a Cisco Router to redirect traffic to the squid box via
WCCP

2) 12.4(15)T8 or higher IOS on the router

3) In my setups, the squid box is always Layer 2 adjacent to the Cisco
router, either through a dedicated interface, or a sub-interface.

4) The ability to compile and install a Linux kernel. Please note that
in these steps, I am NOT using a redhat kernel, nor am I using the
RedHat method of building a kernel.

5) Some steps outlined here can be achieved through several different
means, follow the steps exactly before emailing me or the list, as I
have tested other methods, and they don't always work (case in point:
GRE tunnel interface creation.)

6) This setup assumes a separate WCCP service group for each direction
of the HTTP connection, this is not needed, but makes the setup more
scalable. If you choose to do it a different way, then YMMV. 

In the kernel build specific steps, I actually include possibly to much
information, as well as tell you to enable things that are not always
needed for TPROXY related functionality, or never related to TPROXY
functionality. I included them because they fit more environments, and
thus less time wasted by people asking me questions, not that I mind but
I don't have enough time to answer all the emails I get. I tried to
prepare this information out without errors, if the steps don't work,
email me with the details of where you had problems so that I can adjust
the steps below. At the end the steps below are some common things to
watch for in the steps that can cause the setup not to work.


Steps

1) Install CentOS 5.3, make sure you install nothing other than the base
packages, and trim even those down. I tend to install specific packages
from the distro later. 

Note: I suggest that you make separate partition(s) for where squid will
actually store its caches. Later mount these partitions with specific
options (like "noatime") that will help increase performance.

2) In the initial ncurses-based setup screen, turn off services that you
don't need, and turn off selinux compeletely.

3) After install and initial bootup and configuration, run "yum update"
to update the system for fixes, etc. Then reboot.

4) After step 2, issue this yum command:

yum install libcap libcap-devel gcc gcc-c++ bison flex yacc autoconf
automake ncurses ncurses-devel rpm-devel libpcap tcpdump

Note: let it install other dependency packages. The command above
installs compiles, utilities, etc.


5) Download iptables-1.4.3.2 from netfilter.org

6) Download kernel 2.6.30 from kernel.org

7) Download squid-3.1.0.8 from squid.org

8) Decompress the kernel source, I decompress it to /usr/src/, although
I have read all over the place that this is a bad thing to do. The
location really does not have to be /usr/src/

9) Go into the kernel source directory, issue the following command:
cp /boot/config-2.6.18-128.1.14.el5 ./RH-config-boxed.config

10) Issue this command: make menuconfig

11) When the ncurses-based kernel config screen loads, select the "Load
an Alternate Configuration File" and type in the full path to the
RH-config-boxed.config. This will load the current kernel config, and
there may be some errors, all of which can be ignored.


12) Configure the kernel as you normally would, but be sure to enable
the following:

In "Networking support -> Networking options"

Enable (not as modules):
Packet socket
Packet socket: mmapped IO
TCP/IP networking
IP: advanced router
IP: policy routing

Enable (as modules):
IP: tunneling

Enable (not as modules):
IP: GRE tunnels over IP
IP: broadcast GRE over IP
Network packet filtering framework (Netfilter)


In "Networking support -> Networking options -> Network packet filtering
framework (Netfilter)"

Enable (not as modules):
Advanced netfilter configuration


In "Networking support -> Networking options -> Network packet filtering
framework (Netfilter) -> Core Netfilter 

Configuration"

Enable (as modules):
Netfilter connection tracking support

Enable (not as modules):
Connection tracking security mark support
Connection tracking events

Enable (as modules):
Connection tracking netlink interface
Transparent proxying support (EXPERIMENTAL)
Netfilter Xtables support (required for ip_tables)
"CONNMARK" target support
"MARK" target support 
"TPROXY" target support (EXPERIMENTAL)
"connmark" connection mark match support
"conntrack" connection tracking match support
"mark" match support
"socket" match support (EXPERIMENTAL)
"state" match support


In "Networking support -> Networking options -> Network packet filtering
framework (Netfilter) -> IP: Netfilter Configuration"

Enable (as modules):
IPv4 connection tracking support (required for NAT)
IP tables support (required for filtering/masq/NAT)
Full NAT
MASQUERADE target support
REDIRECT target support
Packet mangling


13) After setting the above options, and any other items you want, exit
out of the kernel config, saving your changes. It will save the kernel
compile config to RH-config-boxed.config so issue the following command
to put the new config in the right 

place:

cp RH-config-boxed.config config-centos

Then do the make, make_install_modules, make install, if no errors,
adjust grub.conf to boot to the new kernel. The reboot to 

the new kernel.

14) Assuming the kernel compiled, installed and booted properly, it is
time to update iptables. Decompress the iptables 

source, and use the following configure command:

./configure --enable-devel --enable-libipq --bindir=/bin --sbindir=/sbin
--sysconfdir=/etc --with-kernel=<path to new kernel source dir>
--with-kbuild=<path to new kernel source dir> --with-ksource=<path to
new kernel source dir>


Then do the make, make install



15) Edit ld.so.conf to add a library path:

vim /etc/ld.so.conf

add a line to the end of the file: /usr/local/lib


16) I suggest rebooting, just to make sure that iptables upgrade is
working. Do a reboot, then do a "service iptables status" to make sure
that iptables is running fine. If it is not running ok, it will show
either a status failed, or an empty rule set.

17) Assuming that the iptables upgrade is working fine, the next steps
are to add the rules and interfaces needed for WCCP and TPROXY
functionality. First, issue a "insmod ip_gre", then do a "dmesg | tail"
and make sure that you see "GRE over IPv4 tunneling driver" if you don't
see anything, or you get an error from insmod, you either compiled GRE
not as a kernel module, or not at all.

18) Create the GRE tunnel interface, issue "ifconfig gre0 <ip address of
squid server> netmask <netmask of squid server ip> up"

19) Issue an "ifconfig" and make sure you see a gre0 interface.

20) Next we need to add iptables rules to allow traffic to the gre
interface itself, gre protocol traffic across the Ethernet interface,
and WCCP traffic from the router. We will do this by editing the
iptables save file directly. Do the following:

a.) service iptables save
b.) vim /etc/sysconfig/iptables
c.) just after the line that says ":RH-Firewall-1-INPUT - [0:0]" add the
following:
        -A INPUT -i gre0 -j ACCEPT 
        -A INPUT -p gre -j ACCEPT 
        -A INPUT -i eth0 -p gre -j ACCEPT
d.) Somewhere lower in the file where the "-A RH-Firewall-1-INPUT" rules
are, add the following:
        -A RH-Firewall-1-INPUT -s <address of cisco router>/32 -p udp -m
udp --dport 2048 -j ACCEPT 
        
        NOTE: The "<address of cisco router>" in this instance is the ip
address of the router that the squid box itself uses. 

Port 2048 is the port that WCCP traffic uses.

e.) save the file and exit vim. Do a "service iptables restart" to make
sure you don't get any errors.


21) Next we add the TPROXY related iptables rules, from the command line
prompt issue the following commands:

iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY
--tproxy-mark 0x1/0x1 --on-port <port squid listens to> --on-ip 

<squid server ip>

22) Assuming the commands in step 21 didn't give errors, do a "service
iptables save"

23) We need to edit the iptables rule order, to make sure it is in the
correct order: "vim /etc/sysconfig/iptables" and make sure the section
at the bottom of the file, from the ":DIVERT - [0:0]" onward looks
something like:

-A DIVERT -j MARK --set-xmark 0x1/0xffffffff
-A DIVERT -j ACCEPT
-A PREROUTING -p tcp -m socket -j DIVERT 
-A PREROUTING -p tcp -m tcp --dport 80 -j TPROXY --on-port <squid port>
--on-ip <squid server ip> --tproxy-mark 0x1/0x1 

When doing the cli commands in step 21, iptables puts the rules in the
wrong order for them to work for TPROXY.

Save the file and exit vim.


24)  do a "service iptables restart"

26) Issue the following commands, per the TPROXY wiki article: 

ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

If no errors from the two commands, add them to the end of
/etc/rc.d/rc.local


27) I'm not sure this is needed anymore, but it doesn't seem to break
anything, so add the following line to the end of /etc/rc.d/rc.local:
echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind

28) In the beginning of the rc.local file, add the following two lines:

modprobe ip_gre
<the ifconfig gre0 command line from step 18 above>


29) Edit /etc/sysctl.conf, make sure there is a line somewhere that
says:

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

30) Reboot the server

31) Next, build you squid 3.1.x.x, make sure that pass
"--enable-linux-netfilter" to the configure directive, build and install
squid.

32) You will need to edit the squid config to make sure that it has what
it needs to use TPROXY and WCCP. For tproxy, you need one item, the
"http_port" directive needs tproxy appended to it, I do the following:
http_port <ip of squid server>:<port to bind to, "squid port" from step
23 above> tproxy disable-pmtu-discovery=always

33) Configure the WCCP specific related items in the squid config file,
specifically:

        a) wccp2_router <router address used in the steps above>
        b) wccp_version 2
        c) wccp2_rebuild_wait on
        d) wccp2_fowarding_method 1
        e) wccp2_return_method 1
        f) wccp2_assigment_method 1
        g) wccp2_service dynamic 80
        h) wccp2_service dynamic 90
        i) wccp2_service_info 80 protocol=tcp flags=src_ip_hash
priority=240 ports=80
        j) wccp2_service_info 90 protocol=tcp
flags=dst_ip_hash,ports_source priority=240 ports=80

34) There are other squid configuration items that are need which are
not included here because they are not specific to WCCP/TPROXY
functionality and the specifics vary by environment.

35) In the router configuration, you need to do at least the following:
        a.) enable wccp globally with (this might actually be optional):
ip wccp web-cache
        b.) enable the specific services:
                1.) ip wccp 80
                2.) ip wccp 90
                Note: I use a redirect list ACL with the two commands
above so that the router doesn't WCCP redirect specific web sites. The
command would look like "ip wccp 80 redirect-list 122", and access-list
122 would be a list of denies for sites to not be redirected, and a
permit any any at the end of the access-list to allow all other websites
to be wccp redirected.
        c.) On the interface that is adjacent to the squid box, do a "ip
wccp redirect exclude in" this command makes it so that the router does
not redirect the squid traffic as well as other client traffic.



Some things to check along the way:

1) Make sure that the GRE interface on the squid box is seeing packets
coming in. You should never see any packets going out the GRE interface,
and you will only see packets coming in the GRE interface after the WCCP
process on the router redirects them to the squid box.

2) Keep in mind that you should separate the idea in your mind between
WCCP traffic and tunneled HTTP traffic. The router and the squid process
talk to each other for status and service information with WCCP. HTTP
traffic received from the client by the router for redirect is
encapsulated in GRE (to preserve it) and then forwarded to the GRE
interface.

3) The global command "show ip wccp" is a useful router command. In the
output of this command, you should see two "Service Identifier" sections
(one for 80, one for 90 if you use my setup steps.) Within each "Service
Identifier" group, the number of service group clients and routers
should each be 1. If they are not, them some facet of WCCP conversation
between the router and the squid server is not working. Check the
iptables port 2048 setup step 20 part d above.

4) wccp event debug commands are useful. Use "debug ip wccp events" and
set you router logging to debug level to see "Hello" and "Here_I_am"
packets. You need to make sure you see both to insure that the router
and squid box are WCCP talking.

5) Surf the Web from a client and see if you get to a web site. If it
doesn't work, check the items above, recheck the steps. 

It if does work, go to a site that tells you your IP to make sure TPROXY
is working and using the client IP and not the squid IP. It is entirely
possible that the whole setup will work, but not the client IP spoofing.
I also suggest that you burn the setup in with web surfing to make sure
it doesn't break.

I am interested to here people's feedback so that I can improve the
steps above, as well as share optimizations.

Nick




Reply via email to