Hi, Here is the second cut of the linux tproxy patch aiming for inclusion with squid-2.5 branch. The diff is versus squid-2.5.STABLE1. Comments are most welcome :)
The patch adds a new onoff config 'linux_tproxy' (if you configure with
--enable-linux-tproxy) which when set will spoof the source address of
outgoing server connections to be the same as the original client
address. To take advantage of this code you need Linux 2.4 with
netfilter and with the TPROXY patches installed from:
http://www.balabit.com/downloads/tproxy/linux-2.4/
There are four small nits with the code:
1. Server persistent connections are mutually exclusive with this patch.
This is because squid will use any connection to server X, but that
pre-existing connection may be spoofed from a different users IP.
2. You must supply a tcp_outgoing_address in your squid.conf, this is
because of some deep magic in the Linux TCP/IP stack. If anyone would
like me to explain the reasons more thoroughly just ask.
3. Squid must run as root in order to do the connection spoofing bits.
4. I have not tested the autoconf stuff because both my debian and rh8
automakes and autoconfs (of varying versions) all failed for one
reason or another.
Anyone got any advice on what auto(conf|make) versions I should be
using? Would you accept patches to make it work on my version (if they
are correct of course)?
TODO:
o Fix server pconns.
o Port all changes to cvs HEAD branch.
o Attempt to fix connect(2) problem in kernel which requires bind(2) to
local address.
o Fix kernel space code so squid doesn't need to run as root.
o TPROXY as it is breaks end-to-end requirement of the internet, need
to develop a better API for controlling these features from
userspace.
Enjoy! :)
--
// Gianni Tedesco (gianni at scaramanga dot co dot uk)
lynx --source www.scaramanga.co.uk/gianni-at-ecsc.asc | gpg --import
8646BE7D: 6D9F 2287 870E A2C9 8F60 3A3C 91B5 7669 8646 BE7D
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 <linux/netfilter_ipv4.h>
+#endif
+#if LINUX_TPROXY
+#include <linux/netfilter_ipv4/ip_tproxy.h>
+#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
signature.asc
Description: This is a digitally signed message part
