diff -ur squid-2.5.STABLE1.orig/configure.in squid-2.5.STABLE1.tproxy/configure.in --- squid-2.5.STABLE1.orig/configure.in Tue Sep 24 21:00:03 2002 +++ squid-2.5.STABLE1.tproxy/configure.in Mon Mar 10 16:07:42 2003 @@ -746,6 +746,17 @@ fi ]) +dnl Enable Linux transparent proxy support +AC_ARG_ENABLE(linux-tproxy, +[ --enable-linux-tproxy + Enable real Transparent Proxy support for Netfilter TPROXY.], +[ if test "$enableval" = "yes" ; then + echo "Linux Netfilter/TPROXY enabled" + AC_DEFINE(LINUX_TPROXY) + LINUX_TPROXY="yes" + fi +]) + AM_CONDITIONAL(MAKE_LEAKFINDER, false) dnl Enable Leak Finding Functions AC_ARG_ENABLE(leakfinder, @@ -1153,6 +1164,7 @@ libc.h \ limits.h \ linux/netfilter_ipv4.h \ + linux/netfilter_ipv4/ip_tproxy.h \ malloc.h \ math.h \ memory.h \ @@ -1764,6 +1776,27 @@ sleep 10 fi +dnl Linux Netfilter/TPROXY support requires some specific header files +dnl Shamelessly copied from shamelessly copied from above +if test "$LINUX_TPROXY" ; then + AC_MSG_CHECKING(if TPROXY header files are installed) + # hold on to your hats... + if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes"; then + LINUX_TPROXY="yes" + AC_DEFINE(LINUX_TPROXY, 1) + else + LINUX_TPROXY="no" + AC_DEFINE(LINUX_TPROXY, 0) + fi + AC_MSG_RESULT($LINUX_TPROXY) +fi +if test "$LINUX_TPROXY" = "no" ; then + echo "WARNING: Cannot find TPROXY headers, you need to install the" + echo "tproxy package from:" + echo " - lynx http://www.balabit.com/downloads/tproxy/linux-2.4/" + sleep 10 +fi + if test -z "$USE_GNUREGEX" ; then case "$host" in *-sun-solaris2.[[0-4]]) diff -ur squid-2.5.STABLE1.orig/src/cf.data.pre squid-2.5.STABLE1.tproxy/src/cf.data.pre --- squid-2.5.STABLE1.orig/src/cf.data.pre Wed Sep 4 14:35:01 2002 +++ squid-2.5.STABLE1.tproxy/src/cf.data.pre Mon Mar 10 16:06:42 2003 @@ -3837,4 +3837,20 @@ until all the child processes have been started. DOC_END +NAME: linux_tproxy +IFDEF: LINUX_TPROXY +COMMENT: on|off +TYPE: onoff +LOC: Config.onoff.linux_tproxy +DEFAULT: off +DOC_START + If you have Linux 2.4 with netfilter and TPROXY support and you + have compiled squid with the correct options then you can enable + this option to allow squid to spoof the source address of + outgoing connections to servers so that they see connections from + the original client IP addresses. Enable this only if you know + what you are doing. You will need to disable server peristent + connections and set a valid tcp_outgoing_address. +DOC_END + EOF diff -ur squid-2.5.STABLE1.orig/src/client_side.c squid-2.5.STABLE1.tproxy/src/client_side.c --- squid-2.5.STABLE1.orig/src/client_side.c Mon Sep 23 05:04:03 2002 +++ squid-2.5.STABLE1.tproxy/src/client_side.c Mon Mar 10 16:06:03 2003 @@ -322,6 +322,7 @@ new_request->http_ver = old_request->http_ver; httpHeaderAppend(&new_request->header, &old_request->header); new_request->client_addr = old_request->client_addr; + new_request->client_port = old_request->client_port; new_request->my_addr = old_request->my_addr; new_request->my_port = old_request->my_port; new_request->flags.redirected = 1; @@ -2977,6 +2978,7 @@ safe_free(http->log_uri); http->log_uri = xstrdup(urlCanonicalClean(request)); request->client_addr = conn->peer.sin_addr; + request->client_port = conn->peer.sin_port; request->my_addr = conn->me.sin_addr; request->my_port = ntohs(conn->me.sin_port); request->http_ver = http->http_ver; diff -ur squid-2.5.STABLE1.orig/src/forward.c squid-2.5.STABLE1.tproxy/src/forward.c --- squid-2.5.STABLE1.orig/src/forward.c Mon Apr 1 13:51:27 2002 +++ squid-2.5.STABLE1.tproxy/src/forward.c Mon Mar 10 15:50:44 2003 @@ -36,6 +36,13 @@ #include "squid.h" +#if LINUX_NETFILTER +#include +#endif +#if LINUX_TPROXY +#include +#endif + static PSC fwdStartComplete; static void fwdDispatch(FwdState *); static void fwdConnectStart(void *); /* should be same as EVH */ @@ -331,6 +338,11 @@ time_t ctimeout; struct in_addr outgoing; unsigned short tos; +#if LINUX_TPROXY + int f=ITP_CONNECT; + struct in_tproxy itp; +#endif + assert(fs); assert(fwdState->server_fd == -1); debug(17, 3) ("fwdConnectStart: %s\n", url); @@ -396,6 +408,23 @@ ctimeout, fwdConnectTimeout, fwdState); +#if LINUX_TPROXY + if ( Config.onoff.linux_tproxy ) { + itp.itp_faddr.s_addr = fwdState->src.sin_addr.s_addr; + itp.itp_fport = fwdState->src.sin_port; + + /* If these syscalls fail then we just fallback to connecting + * normally by simply ignoring the errors... + */ + setsockopt(fd, SOL_IP, IP_TPROXY_ASSIGN, &itp, sizeof(itp)); + setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &f, sizeof(f)); + + debug(17, 1) ("tproxy: %s:%u -> %s:%u\n", + inet_ntoa(fwdState->src.sin_addr), + htons(fwdState->src.sin_port), + host, port); + } +#endif commConnectStart(fd, host, port, fwdConnectDone, fwdState); } @@ -610,6 +639,15 @@ fwdState->server_fd = -1; fwdState->request = requestLink(r); fwdState->start = squid_curtime; + +#if LINUX_TPROXY + /* If we need to transparently proxy the request + * then we need the client source address and port */ + fwdState->src.sin_family = AF_INET; + fwdState->src.sin_addr = r->client_addr; + fwdState->src.sin_port = r->client_port; +#endif + storeLockObject(e); EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT); storeRegisterAbort(e, fwdAbort, fwdState); diff -ur squid-2.5.STABLE1.orig/src/main.c squid-2.5.STABLE1.tproxy/src/main.c --- squid-2.5.STABLE1.orig/src/main.c Sun Jul 14 18:20:49 2002 +++ squid-2.5.STABLE1.tproxy/src/main.c Mon Mar 10 15:50:44 2003 @@ -422,6 +422,16 @@ #ifdef _SQUID_OS2_ return; #endif + + /* Transparent proxy support requires squid to run as root which + * kinda sucks. I will look towards implementing a solution in + * kernel space to combat this, perhaps a sysctl to set a certain + * GID to be able to use the TPROXY stuff */ +#if LINUX_TPROXY + if ( Config.onoff.linux_tproxy ) + return; +#endif + if (geteuid() == 0) { debug(0, 0) ("Squid is not safe to run as root! If you must\n"); debug(0, 0) ("start Squid as root, then you must configure\n"); @@ -467,6 +477,14 @@ squid_signal(SIGPIPE, SIG_IGN, SA_RESTART); squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART); +#if LINUX_TPROXY + if ( Config.onoff.linux_tproxy && Config.onoff.server_pconns ) { + Config.onoff.server_pconns=0; + debug(1, 1) ("Disabling server pconns, mutually exclusive " + "with linux_tproxy."); + } +#endif + setEffectiveUser(); assert(Config.Sockaddr.http); if (httpPortNumOverride != 1) diff -ur squid-2.5.STABLE1.orig/src/structs.h squid-2.5.STABLE1.tproxy/src/structs.h --- squid-2.5.STABLE1.orig/src/structs.h Sun Sep 8 00:11:23 2002 +++ squid-2.5.STABLE1.tproxy/src/structs.h Mon Mar 10 16:06:03 2003 @@ -585,6 +585,9 @@ int ie_refresh; int vary_ignore_expire; int pipeline_prefetch; +#if LINUX_NETFILTER + int linux_tproxy; +#endif } onoff; acl *aclList; struct { @@ -1645,6 +1648,7 @@ int imslen; int max_forwards; /* these in_addr's could probably be sockaddr_in's */ + in_port_t client_port; struct in_addr client_addr; struct in_addr my_addr; unsigned short my_port; @@ -1962,6 +1966,9 @@ unsigned int dont_retry:1; unsigned int ftp_pasv_failed:1; } flags; +#if LINUX_NETFILTER + struct sockaddr_in src; +#endif }; #if USE_HTCP