fi
dnl Enable Linux transparent proxy support
--AC_ARG_ENABLE(linux-tproxy,
--[ --enable-linux-tproxy
-- Enable real Transparent Proxy support for Netfilter TPROXY.],
++AC_ARG_ENABLE(linux-tproxy2,
++[ --enable-linux-tproxy2
++ Enable real Transparent Proxy support for Netfilter TPROXY (version 2).],
[ if test "$enableval" = "yes" ; then
-- echo "Linux Netfilter/TPROXY enabled"
-- AC_DEFINE(LINUX_TPROXY, 1, [Enable real Transparent Proxy support for Netfilter TPROXY.])
-- LINUX_TPROXY="yes"
++ echo "Linux Netfilter/TPROXY v2 enabled"
++ AC_DEFINE(LINUX_TPROXY2, 1, [Enable real Transparent Proxy support for Netfilter TPROXY v2.])
++ LINUX_TPROXY2="yes"
++ if test -z "$LINUX_NETFILTER"; then
++ echo "Linux-Netfilter Transparent Proxy automatically enabled"
++ LINUX_NETFILTER="yes"
++ fi
++ fi
++])
++AC_ARG_ENABLE(linux-tproxy4,
++[ --enable-linux-tproxy4
++ Enable real Transparent Proxy support for Netfilter TPROXY (version 4+).],
++[ if test "$enableval" = "yes" ; then
++ echo "Linux Netfilter/TPROXY v4 enabled"
++ AC_DEFINE(LINUX_TPROXY4, 1, [Enable real Transparent Proxy support for Netfilter TPROXY v4.])
++ LINUX_TPROXY4="yes"
if test -z "$LINUX_NETFILTER"; then
echo "Linux-Netfilter Transparent Proxy automatically enabled"
LINUX_NETFILTER="yes"
sleep 10
fi
--dnl Linux Netfilter/TPROXY support requires some specific header files
++dnl Linux Netfilter/TPROXYv2 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)
++if test "$LINUX_TPROXY2" ; then
++ AC_MSG_CHECKING(if TPROXYv2 header files are installed)
# hold on to your hats...
if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then
-- LINUX_TPROXY="yes"
-- AC_DEFINE(LINUX_TPROXY, 1, [Enable real Transparent Proxy support for Netfilter TPROXY.])
++ LINUX_TPROXY2="yes"
++ AC_DEFINE(LINUX_TPROXY2, 1, [Enable real Transparent Proxy support for Netfilter TPROXY v2.])
else
-- LINUX_TPROXY="no"
-- AC_DEFINE(LINUX_TPROXY, 0, [Enable real Transparent Proxy support for Netfilter TPROXY.])
++ LINUX_TPROXY2="no"
++ AC_DEFINE(LINUX_TPROXY2, 0, [Enable real Transparent Proxy support for Netfilter TPROXY v2.])
++ fi
++ AC_MSG_RESULT($LINUX_TPROXY2)
++ if test "$LINUX_TPROXY2" = "no" && test "$LINUX_NETFILTER" = "yes"; then
++ echo "WARNING: Cannot find TPROXY v2 headers, you need to install the"
++ echo "tproxy package from:"
++ echo " - lynx http://www.balabit.com/downloads/tproxy/"
++ echo "Or select the '--enable-linux-tproxy4' option instead."
++ sleep 10
fi
-- AC_MSG_RESULT($LINUX_TPROXY)
--fi
--if test "$LINUX_TPROXY" = "no" && test "$LINUX_NETFILTER" = "yes"; then
-- echo "WARNING: Cannot find TPROXY headers, you need to install the"
-- echo "tproxy package from:"
-- echo " - lynx http://www.balabit.com/downloads/tproxy/"
-- sleep 10
fi
if test -z "$USE_GNUREGEX" ; then
/* Enable support for Transparent Proxy on Linux (Netfilter) systems */
#undef LINUX_NETFILTER
--/* Enable real Transparent Proxy support for Netfilter TPROXY. */
--#undef LINUX_TPROXY
++/* Enable real Transparent Proxy support for Netfilter TPROXY v2. */
++#undef LINUX_TPROXY2
++
++/* Enable real Transparent Proxy support for Netfilter TPROXY v4. */
++#undef LINUX_TPROXY4
/* If we need to declare sys_errlist[] as external */
#undef NEED_SYS_ERRLIST
--
/*
* $Id: IPInterception.cc,v 1.20 2008/02/05 22:38:24 amosjeffries Exp $
*
#include <linux/netfilter_ipv4.h>
#endif
--#if IPF_TRANSPARENT
int
--
clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
{
++
++#if IPF_TRANSPARENT /* --enable-ipf-transparent */
++
dst = me;
if( !me.IsIPv4() ) return -1;
if( !peer.IsIPv4() ) return -1;
return 0;
}
--}
--#elif LINUX_NETFILTER
--int
--clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
--{
++
++
++#elif LINUX_NETFILTER || LINUX_TPROXY4 /* --enable-linux-netfilter OR --enable-linux-tproxy4 */
++
dst = me;
if( !me.IsIPv4() ) return -1;
if( !peer.IsIPv4() ) return -1;
dst.GetAddrInfo(lookup,AF_INET);
++#if LINUX_NETFILTER
if (getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, lookup->ai_addr, &lookup->ai_addrlen) != 0)
++#elif LINUX_TPROXY4
++ if (getsockopt(fd, SOL_IP, IP_TRANSPARENT, lookup->ai_addr, &lookup->ai_addrlen) != 0)
++#endif
{
dst.FreeAddrInfo(lookup);
if (squid_curtime - last_reported > 60) {
-- debugs(89, 1, "clientNatLookup: peer " << peer << " NF getsockopt(SO_ORIGINAL_DST) failed: " << xstrerror());
++ debugs(89, 1, "clientNatLookup: peer " << peer << " NF getsockopt(" << (LINUX_NETFILTER?"SO_ORIGINAL_DST":"IP_TRANSPARENT") << ") failed: " << xstrerror());
last_reported = squid_curtime;
}
return 0;
else
return -1;
--}
--#elif PF_TRANSPARENT
--int
--clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress dst)
--{
++#elif PF_TRANSPARENT /* --enable-pf-transparent */
struct pfioc_natlook nl;
static int pffd = -1;
else
return -1;
}
--}
--#elif IPFW_TRANSPARENT
--int
--clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
--{
++
++#elif IPFW_TRANSPARENT /* --enable-ipfw-transparent */
++
int ret;
struct addrinfo *lookup = NULL;
dst.FreeAddrInfo(lookup);
return 0;
--}
--#else
--int
--clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
--{
++
++#else /* none of the transparent options configured */
++
debugs(89, 1, "WARNING: transparent proxying not supported");
return -1;
--}
++
#endif
++}
--
/*
* $Id: IPInterception.h,v 1.7 2007/12/14 23:11:45 amosjeffries Exp $
*
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
*/
--
#ifndef SQUID_IPINTERCEPTION_H
#define SQUID_IPINTERCEPTION_H
#include "IPAddress.h"
--SQUIDCEXTERN int
--clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst);
++#if LINUX_TPROXY4 && !defined(IP_TRANSPARENT)
++#define IP_TRANSPARENT 19
++#endif
++
++SQUIDCEXTERN int clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst);
#endif /* SQUID_IPINTERCEPTION_H */
int vport; /* virtual port support, -1 for dynamic, >0 static*/
int disable_pmtu_discovery;
--#if LINUX_TPROXY
- unsigned int tproxy:
- 1; /* spoof client ip using tproxy */
++
++#if LINUX_TPROXY2 || LINUX_TPROXY4
+ unsigned int tproxy:1; /* spoof client ip using tproxy */
#endif
struct {
--
/*
* $Id: cache_cf.cc,v 1.544 2008/03/04 12:00:36 amosjeffries Exp $
*
else
self_destruct();
--#if LINUX_TPROXY
++#if LINUX_TPROXY2 || LINUX_TPROXY4
} else if (strcmp(token, "tproxy") == 0) {
s->tproxy = 1;
}
#endif
#endif
++
} else if (strcmp(token, "ipv4") == 0) {
#if USE_IPV6
if( !s->s.SetIPv4() ) {
request->flags.transparent = http->flags.transparent;
--#if LINUX_TPROXY
--
++#if LINUX_TPROXY2 || LINUX_TPROXY4
request->flags.tproxy = conn->port->tproxy && need_linux_tproxy;
#endif
if (fd < 0)
continue;
++#if LINUX_TPROXY4
++ /* because the transparent/non-transparent port info is only known here.
++ * we have to set the IP_TRANSPARENT option here. */
++ if(s->transparent)
++ comm_set_transparent(fd,0);
++#endif
++
comm_listen(fd);
comm_accept(fd, httpAccept, s);
#endif /* sockopt */
}
++void
++comm_set_transparent(int fd, int tos)
++{
++#if LINUX_TPROXY4
++ if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, (char *) &tos, sizeof(int)) < 0) {
++ debugs(50, 1, "comm_open: setsockopt(IP_TRANSPARENT) on FD " << fd << ": " << xstrerror());
++ }
++#else
++ debugs(50, 0, "WARNING: comm_open: setsockopt(IP_TRANSPARENT) not supported on this platform");
++#endif /* sockopt */
++}
++
/**
* Create a socket. Default is blocking, stream (TCP) socket. IO_TYPE
* is OR of flags specified in defines.h:COMM_*
#include "SquidTime.h"
#include "Store.h"
--#if LINUX_TPROXY
++#if LINUX_TPROXY2
++#ifdef HAVE_LINUX_NETFILTER_IPV4_IP_TPROXY_H
#include <linux/netfilter_ipv4/ip_tproxy.h>
++#else
++#error " TPROXY v2 Header file missing: linux/netfilter_ipv4/ip_tproxy.h. Perhapse you meant to use TPROXY v4 ? "
++#endif
#endif
static PSC fwdStartCompleteWrapper;
struct
{
-
- unsigned int dont_retry:
- 1;
-
- unsigned int ftp_pasv_failed:
- 1;
-
- unsigned int forward_completed:1;
- }
-
- flags;
- #if LINUX_NETFILTER
+ unsigned int dont_retry:1;
+ unsigned int ftp_pasv_failed:1;
+ unsigned int forward_completed:1;
+ } flags;
-#if LINUX_NETFILTER
++#if LINUX_NETFILTER || LINUX_TPROXY2 || LINUX_TPROXY4
IPAddress src;
#endif
extern const char *external_acl_message; /* NULL */
extern int opt_send_signal; /* -1 */
extern int opt_no_daemon; /* 0 */
--#if LINUX_TPROXY
++#if LINUX_TPROXY2 || LINUX_TPROXY4
extern int need_linux_tproxy; /* 0 */
#endif
comm_remove_close_handler(fd, closeHandler);
closeHandler = NULL;
fwd->unregister(fd);
--#if LINUX_TPROXY
++
++#if LINUX_TPROXY2 || LINUX_TPROXY4
if (orig_request->flags.tproxy)
client_addr = orig_request->client_addr;
#if HTTP_VIOLATIONS
nocache_hack = 0;
#endif
--#if LINUX_TPROXY
++#if LINUX_TPROXY2 || LINUX_TPROXY4
tproxy = 0;
#endif
-
}
- unsigned int range:
- 1;
-
- unsigned int nocache:
- 1;
-
- unsigned int ims:
- 1;
-
- unsigned int auth:
- 1;
-
- unsigned int cachable:
- 1;
-
- unsigned int hierarchical:
- 1;
-
- unsigned int loopdetect:
- 1;
-
- unsigned int proxy_keepalive:
- 1;
-
- unsigned int proxying:
- 1; /* this should be killed, also in httpstateflags */
-
- unsigned int refresh:
- 1;
-
- unsigned int redirected:
- 1;
-
- unsigned int need_validation:
- 1;
+ unsigned int range:1;
+ unsigned int nocache:1;
+ unsigned int ims:1;
+ unsigned int auth:1;
+ unsigned int cachable:1;
+ unsigned int hierarchical:1;
+ unsigned int loopdetect:1;
+ unsigned int proxy_keepalive:1;
+ unsigned int proxying:1; /* this should be killed, also in httpstateflags */
+ unsigned int refresh:1;
+ unsigned int redirected:1;
+ unsigned int need_validation:1;
#if HTTP_VIOLATIONS
-
- unsigned int nocache_hack:
- 1; /* for changing/ignoring no-cache requests */
+ unsigned int nocache_hack:1; /* for changing/ignoring no-cache requests */
#endif
-
- unsigned int accelerated:
- 1;
-
- unsigned int transparent:
- 1;
-
- #if LINUX_TPROXY
- unsigned int tproxy:
- 1; /* spoof client ip using tproxy */
+ unsigned int accelerated:1;
+ unsigned int transparent:1;
-#if LINUX_TPROXY
++#if LINUX_TPROXY2 || LINUX_TPROXY4
+ unsigned int tproxy:1; /* spoof client ip using tproxy */
#endif
- unsigned int internal:
- 1;
-
- unsigned int internalclient:
- 1;
-
- unsigned int must_keepalive:
- 1;
+ unsigned int internal:1;
+ unsigned int internalclient:1;
+ unsigned int must_keepalive:1;
// When adding new flags, please update cloneAdaptationImmune() as needed.
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
/* Silent failure unless TPROXY is required. Maybe not started as root */
--#if LINUX_TPROXY
++#if LINUX_TPROXY2 || LINUX_TPROXY4
if (need_linux_tproxy)
debugs(1, 1, "Error - tproxy support requires capability setting which has failed. Continuing without tproxy support");
#endif
}
--
#endif
}
cap->inheritable = 0;
cap->effective = (1 << CAP_NET_BIND_SERVICE);
--#if LINUX_TPROXY
++#if LINUX_TPROXY2
if (need_linux_tproxy)
cap->effective |= (1 << CAP_NET_ADMIN) | (1 << CAP_NET_BROADCAST);
++#elif LINUX_TPROXY4
++ if (need_linux_tproxy)
++ cap->effective |= (1 << CAP_NET_ADMIN);
#endif
if (capset(head, cap) != 0) {
/* Silent failure unless TPROXY is required */
--#if LINUX_TPROXY
++#if LINUX_TPROXY2 || LINUX_TPROXY4
if (need_linux_tproxy)
debugs(50, 1, "Error enabling needed capabilities. Will continue without tproxy support");
nocap:
xfree(head);
xfree(cap);
--#else
--#if LINUX_TPROXY
++#else /* not defined(_SQUID_LINUX_) && HAVE_SYS_CAPABILITY_H */
++
++#if LINUX_TPROXY2 || LINUX_TPROXY4
if (need_linux_tproxy)
debugs(50, 1, "Missing needed capability support. Will continue without tproxy support");
need_linux_tproxy = 0;
--
#endif
#endif