Using ZXTM as a transparent proxy

Load Balancers like ZXTM typically sit just in front of a cluster of servers which provide a network service. Traffic for the network service is directed to the load balancer (rather than the server(s)), and the load balancer then distributes the traffic across the servers. This configuration is sometimes referred to as a 'reverse proxy'.

With a little iptables configuration, you can configure ZXTM to run in a 'transparent' manner, managing traffic which is not explicitly addressed to the ZXTM machine. This is useful in a 'forward proxy' configuration, where ZXTM proxies the traffic for a number of clients rather than a number of servers.

This article explains how to configure ZXTM as a forward proxy for HTTP traffic, while letting all other traffic through. ZXTM will load-balance HTTP traffic across a cluster of Squid caching proxy servers; the squid servers will then forward the traffic to the correct destination.

The network layout

Here's a quick network diagram...

192.168.1.* 192.168.1.1 External IP
Client1 | |
Client2 -------- gateway server ---+------ Internet
Client3 (running ZXTM) |
| |
+-- squid1 --+
| |
+-- squid2 --+

Clients run on 192.168.1.*, with a default gateway of 192.168.1.1. 192.168.1.1 can route traffic to the internet and is configured to masquerade packets (eth0 is the WAN interface):

# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

So, clients on the 192.168.1.* network can directly access servers on the internet, NAT'ed through the gateway server.

ZXTM and Squid Configuration

Now, install ZXTM on the gateway server 192.168.1.1, listening on port 3128 and load-balancing traffic onto two servers (squid1:3128, squid2:3128).

Install the squid software (http://www.squid-cache.org/) onto the servers squid1 and squid2, making the following configuration changes to /usr/local/squid/etc/squid.conf:

# listen on port 3128
http_port 3128
# Allow anyone to access (need to fine-tune this)
http_access allow all
# For the transparent proxying...
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on

Run /usr/local/squid/sbin/squid -z to initialize the cache directories (you may need to chmod /usr/local/squid/var/ so that the nobody user can write to it), then start squid up in debug mode (for testing) as:

/usr/local/squid/sbin/squid -NCd1

Finally, we need to configure the gateway machine that is running ZXTM to intercept all traffic to port 80 (HTTP) and deliver it to the local ZXTM software. The following iptables command does so, rewriting all tcp traffic to port 80 to localhost:3128:

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3128

Now, traffic to port 80 will be rewritten on the gateway to localhost:3128. The ZXTM listening on port 3128 will terminate the connection.

ZXTM will load-balance the requests across the two proxy servers. The proxy servers will request the resouce from the http server on the internet and return the result to the ZXTM, which returns it to the client.

You can test this by logging requests in ZXTM (Virtual Server->Access Logging) and by logging requests in the SQUID proxies.

Owen Garrett [Zeus Dev Team] 01 July 2005 Bookmark with del.icio.us Post this article to Digg Post this article to reddit Post this article to Facebook Tweet this article 3 comments  

Comments:

This public messageboard is not a forum for technical support. To report technical support problems, please contact our dedicated Support team using the instructions at the bottom of this page.

Comment from: Owen Garrett [Zeus Dev Team]
This only works for protocols where the destination node is embedded inside the protocol itself; for example, the 'Host' header in HTTP. This is because once ZXTM recieves the request, it has no way of knowing what the original destination IP was.

Also, ZXTM only balances traffic across a fixed set of nodes (a pool); you can't (yet) tell it to direct the traffic to a random node somewhere. This is why you also need to use a proxy server such as squid (which looks at the URL and host header and sends the request accordingly).

Finally, you can't do this seamlessly with SSL-wrapped protocols such as HTTPS because the certificate that ZXTM presents to the client won't match the certificate on the remote service that the client thinks it has connected to. You'll get a certificate-mismatch error in your browser. And, you'll need to ensure that Squid re-encrypts the traffic to the final server (I think that's possible, but haven't tried).
Permalink 01 July 2005 @ 12:00
Comment from: Stephen Davis [Zeus]
I set up a similar system at a customer's site, which they then used for:

- Allowing/disallowing access to MSN Messenger
- Logging MSN Messenger conversations
- Barring direct access to Windows Update

The clients were told to use a proxy using MS Active Diectory and the address given was ZXTM's VIP. Their firewall was used to block direct access to the Internet.
Permalink 01 July 2005 @ 12:00
Comment from: Owen Garrett [Zeus Dev Team]
A quick update - a couple of ways to select nodes have been introduced in later versions of ZXTM.

You can select a pool using an expression, such as pool.use( http.getHostHeader()), so if you have a small number of sites to forward-proxy to, you can do so by creating a pool for each.

You can also chose a specific node within a pool using the new 'Named Node' session persistence class and the connection.setPersistenceNode() function. net.dns.resolveHost() may help here, but remember that the IP must already be present in the pool.
Permalink 04 January 2007 @ 12:33
Leave a comment ...
Your email address will not be displayed.
Your URL will be displayed.
This public messageboard is not a forum for technical support. To report technical support problems, please contact our dedicated Support team using the instructions at the bottom of this page.
Options:
 
(Line breaks become <br />)
(Set cookies for name, email & url)

Recently...

Other Resources