Index: configure =================================================================== --- configure (revision 9786) +++ configure (working copy) @@ -9554,7 +9554,6 @@ grp.h \ libc.h \ linux/netfilter_ipv4.h \ - linux/netfilter_ipv4/ip_tproxy.h \ malloc.h \ math.h \ memory.h \ @@ -29104,10 +29103,10 @@ fi if test "$LINUX_TPROXY"; then - { $as_echo "$as_me:$LINENO: checking if TPROXY header files are installed" >&5 -$as_echo_n "checking if TPROXY header files are installed... " >&6; } + { echo "$as_me:$LINENO: checking if sys/capability header files are installed" >&5 +echo $ECHO_N "checking if sys/capability header files are installed... $ECHO_C" >&6; } # hold on to your hats... - if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then + if test "$ac_cv_header_sys_capability_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then LINUX_TPROXY="yes" cat >>confdefs.h <<\_ACEOF @@ -29122,8 +29121,12 @@ _ACEOF fi - { $as_echo "$as_me:$LINENO: result: $LINUX_TPROXY" >&5 -$as_echo "$LINUX_TPROXY" >&6; } + { echo "$as_me:$LINENO: result: $LINUX_TPROXY" >&5 +echo "${ECHO_T}$LINUX_TPROXY" >&6; } + + if test "$LINUX_TPROXY" = "no" ; then + echo "WARNING: Cannot find necessary system capability headers files" + echo " Linux TProxy-4 support WILL NOT be enabled" if test "$use_libcap" != "yes"; then { $as_echo "$as_me:$LINENO: WARNING: Missing needed capabilities (libcap or libcap2) for TPROXY" >&5 $as_echo "$as_me: WARNING: Missing needed capabilities (libcap or libcap2) for TPROXY" >&2;} @@ -29131,11 +29134,6 @@ sleep 10 fi fi -if test "$LINUX_TPROXY" = "no" && test "$LINUX_NETFILTER" = "yes"; then - echo "WARNING: Cannot find TPROXY headers, you need to patch your kernel with the" - echo "tproxy package from:" - echo " - lynx http://www.balabit.com/downloads/files/tproxy/" - sleep 10 fi if test -z "$USE_GNUREGEX" ; then Index: configure.in =================================================================== --- configure.in (revision 9786) +++ configure.in (working copy) @@ -1802,7 +1802,6 @@ grp.h \ libc.h \ linux/netfilter_ipv4.h \ - linux/netfilter_ipv4/ip_tproxy.h \ malloc.h \ math.h \ memory.h \ @@ -2946,9 +2945,9 @@ dnl Linux Netfilter/TPROXY support requires some specific header files and libcap dnl Shamelessly copied from shamelessly copied from above if test "$LINUX_TPROXY"; then - AC_MSG_CHECKING(if TPROXY header files are installed) + AC_MSG_CHECKING(if sys/capability 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 + if test "$ac_cv_header_sys_capability_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then LINUX_TPROXY="yes" AC_DEFINE(LINUX_TPROXY, 1, [Enable real Transparent Proxy support for Netfilter TPROXY.]) else @@ -2961,13 +2960,12 @@ LINUX_TPROXY="no" sleep 10 fi + + if test "$LINUX_TPROXY" = "no" ; then + echo "WARNING: Cannot find necessary system capability headers files" + echo " Linux TProxy-4 support WILL NOT be enabled" + fi fi -if test "$LINUX_TPROXY" = "no" && test "$LINUX_NETFILTER" = "yes"; then - echo "WARNING: Cannot find TPROXY headers, you need to patch your kernel with the" - echo "tproxy package from:" - echo " - lynx http://www.balabit.com/downloads/files/tproxy/" - sleep 10 -fi if test -z "$USE_GNUREGEX" ; then case "$host" in Index: src/ssl.c =================================================================== --- src/ssl.c (revision 9786) +++ src/ssl.c (working copy) @@ -499,6 +499,11 @@ char *url = http->uri; struct in_addr outgoing; unsigned long tos; +#ifdef LINUX_TPROXY + int flags; +#endif + + /* * client_addr == no_addr indicates this is an "internal" request * from peer_digest.c, asn.c, netdb.c, etc and should always @@ -522,11 +527,17 @@ outgoing = getOutgoingAddr(request); tos = getOutgoingTOS(request); /* Create socket. */ + flags = COMM_NONBLOCKING; +#ifdef LINUX_TPROXY + if (request->flags.tproxy) { + flags |= COMM_TRANSPARENT; + } +#endif sock = comm_openex(SOCK_STREAM, IPPROTO_TCP, outgoing, 0, - COMM_NONBLOCKING, + flags, tos, url); if (sock == COMM_ERROR) { Index: src/structs.h =================================================================== --- src/structs.h (revision 9786) +++ src/structs.h (working copy) @@ -942,6 +942,7 @@ unsigned int close_on_exec:1; unsigned int backoff:1; /* keep track of whether the fd is backed off */ unsigned int dnsfailed:1; /* did the dns lookup fail */ + unsigned int transparent:1; } flags; comm_pending read_pending; comm_pending write_pending; Index: src/defines.h =================================================================== --- src/defines.h (revision 9786) +++ src/defines.h (working copy) @@ -93,6 +93,9 @@ #define COMM_NONBLOCKING 0x01 #define COMM_NOCLOEXEC 0x02 #define COMM_REUSEADDR 0x04 +#ifdef LINUX_TPROXY +#define COMM_TRANSPARENT 0x08 +#endif #define do_debug(SECTION, LEVEL) \ ((_db_level = (LEVEL)) <= debugLevels[SECTION]) Index: src/comm.c =================================================================== --- src/comm.c (revision 9786) +++ src/comm.c (working copy) @@ -47,6 +47,12 @@ #include #endif +#ifdef LINUX_TPROXY +#ifndef IP_TRANSPARENT +#define IP_TRANSPARENT 19 +#endif +#endif + typedef struct { char *host; u_short port; @@ -65,6 +71,9 @@ static void commSetReuseAddr(int); static void commSetNoLinger(int); static void CommWriteStateCallbackAndFree(int fd, int code); +#ifdef LINUX_TPROXY +static void commSetTransparent(int); +#endif #ifdef TCP_NODELAY static void commSetTcpNoDelay(int); #endif @@ -258,6 +267,12 @@ if (opt_reuseaddr) commSetReuseAddr(new_socket); } +#ifdef LINUX_TPROXY + if (flags & COMM_TRANSPARENT) { + F->flags.transparent = 1; + commSetTransparent(new_socket); + } +#endif if (addr.s_addr != no_addr.s_addr) { if (commBind(new_socket, addr, port) != COMM_OK) { comm_close(new_socket); @@ -435,6 +450,12 @@ * yuck, this has assumptions about comm_open() arguments for * the original socket */ +#ifdef LINUX_TPROXY + if (F->flags.transparent) { + commSetTransparent(cs->fd); + } +#endif + if (commBind(cs->fd, F->local_addr, F->local_port) != COMM_OK) { debug(5, 0) ("commResetFD: bind: %s\n", xstrerror()); return 0; @@ -1534,3 +1555,19 @@ } } } + +#ifdef LINUX_TPROXY +static void +commSetTransparent(int fd) +{ + int on = 1; + debug(5, 3) ("commSetTransparent: FD %d\n", fd); + if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, (char*)&on, sizeof(on)) < 0) { + debug(5, 1) ("commSetTransparent: FD %d: %s\n", fd, xstrerror()); + } + fd_table[fd].flags.transparent = 1; +} +#endif + + + Index: src/forward.c =================================================================== --- src/forward.c (revision 9786) +++ src/forward.c (working copy) @@ -40,9 +40,6 @@ #include #include #endif -#if LINUX_TPROXY -#include -#endif static PSC fwdStartComplete; static void fwdDispatch(FwdState *); @@ -515,7 +512,7 @@ struct in_addr outgoing; unsigned short tos; #if LINUX_TPROXY - struct in_tproxy itp; + int flags; #endif int idle = -1; @@ -624,11 +621,19 @@ debug(17, 3) ("fwdConnectStart: got addr %s, tos %d\n", inet_ntoa(outgoing), tos); + flags = COMM_NONBLOCKING; +#ifdef LINUX_TPROXY + if ((outgoing.s_addr == INADDR_ANY) && fwdState->request->flags.tproxy) { + outgoing = fwdState->request->client_addr; + flags |= COMM_TRANSPARENT; + debug(17,3)("fwdConnectStart: setting outgoing.s_addr=%08X (will set TRANSPARENT)\n", outgoing.s_addr); + } +#endif fd = comm_openex(SOCK_STREAM, IPPROTO_TCP, outgoing, 0, - COMM_NONBLOCKING, + flags, tos, url); if (fd < 0) { @@ -661,32 +666,6 @@ if (fs->peer) { hierarchyNote(&fwdState->request->hier, fs->code, fs->peer->name); } else { -#if LINUX_TPROXY - if (fwdState->request->flags.tproxy) { - - itp.v.addr.faddr.s_addr = fwdState->src.sin_addr.s_addr; - itp.v.addr.fport = 0; - - /* If these syscalls fail then we just fallback to connecting - * normally by simply ignoring the errors... - */ - itp.op = TPROXY_ASSIGN; - if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) { - debug(20, 1) ("tproxy ip=%s,0x%x,port=%d ERROR ASSIGN\n", - inet_ntoa(itp.v.addr.faddr), - itp.v.addr.faddr.s_addr, - itp.v.addr.fport); - } else { - itp.op = TPROXY_FLAGS; - itp.v.flags = ITP_CONNECT; - if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) { - debug(20, 1) ("tproxy ip=%x,port=%d ERROR CONNECT\n", - itp.v.addr.faddr.s_addr, - itp.v.addr.fport); - } - } - } -#endif hierarchyNote(&fwdState->request->hier, fs->code, fwdState->request->host); } Index: src/client_side.c =================================================================== --- src/client_side.c (revision 9786) +++ src/client_side.c (working copy) @@ -5172,6 +5172,7 @@ { http_port_list *s; int fd; + int flags; for (s = Config.Sockaddr.http; s; s = s->next) { if (MAXHTTPPORTS == NHttpSockets) { debug(1, 1) ("WARNING: You have too many 'http_port' lines.\n"); @@ -5193,11 +5194,17 @@ "HTTP Socket"); } else { enter_suid(); + flags = COMM_NONBLOCKING; +#ifdef LINUX_TPROXY + if (s->tproxy) { + flags |= COMM_TRANSPARENT; + } +#endif fd = comm_open(SOCK_STREAM, IPPROTO_TCP, s->s.sin_addr, ntohs(s->s.sin_port), - COMM_NONBLOCKING, + flags, "HTTP Socket"); leave_suid(); }