Adrian Chadd wrote:
>On Thu, Aug 18, 2005, Ken Moberg wrote:
>  
>
>>Source Forge Account: kmoberg
>>Email: sf@kmoberg.net
>>
>>I have patches for Squid-2.5.STABLE9 that use the client's IP address 
>>for all outgoing requests (TPROXY). I'd like to make them available for 
>>people to use.
>>
>>I also have a patch that only rotates the logs when a rotate is 
>>triggered. The old rotate function stops all traffic while it does a 
>>bunch of housekeeping tasks that aren't related to rotating the logs.
>>
>>Where can I upload these patches?
>>    
>>
>
>Just email them here, to the squid-dev list. This way we all see them
>and they're archived.
>
>Adrian
>
>  
>
OK, I finally put the patches together for TPROXY. It uses the client 
address stored in the X-Forwarded-for field of the http header.
Ken
-----------------------------------------------------------------------------------------------------------------------------------------------------
Index: configure.in
749a750,760
 > 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
 > ])
 >
1211a1223
 >     linux/netfilter_ipv4/ip_tproxy.h \
1895a1908,1928
 > 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
 >
Index: src/cf.data.pre
1d0
<
3960a3960,3974
 > DOC_END
 >
 > NAME: 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 set a valid
 >     tcp_outgoing_address.
Index: src/client_side.c
357a358
 >     new_request->client_port = old_request->client_port;
2482a2484
 >     const HttpHeader *req_hdr = &r->header;
2483a2486,2489
 >     String xfwd;
 >    
 >     int status;
 >    
2537a2544,2572
 >
 >     /*
 >      * If we have TPROXY enabled, parse the http header for 
'X-Forwarded-for'.
 >      * If it's there, convert it into an in_addr and put it into the 
request
 >      * structure we pass to forward.
 >      */
 >     if (Config.onoff.linux_tproxy) {
 >         xfwd = httpHeaderGetList(req_hdr, HDR_X_FORWARDED_FOR);
 >         if (xfwd.len != 0) {
 >             debug(33, 2) ("%s: xfwd_ip[%s]\n", __func__, xfwd.buf);
 >             status = inet_aton(xfwd.buf, &r->xfwd_ip);
 >             if (status == 0) {
 >                 r->xfwd_ip.s_addr = htonl(INADDR_ANY);
 >             }
 >         } else {
 >             r->xfwd_ip.s_addr = htonl(INADDR_ANY);
 >         }
 >
 >         if (r->xfwd_ip.s_addr != INADDR_ANY) {
 >             debug(33, 2) ("xfwd: %s:%d\n", inet_ntoa(r->xfwd_ip),
 >                           htons(r->client_port));
 >         } else {
 >             debug(33, 2) ("xfwd: Field Empty [%s]\n",
 >                           inet_ntoa(r->xfwd_ip));
 >         }
 >        
 >            
 >     }
 >    
3133a3169
 >         request->client_port = conn->peer.sin_port;
Index: src/forward.c
1d0
<
38a38,40
 > #include <linux/netfilter_ipv4.h>
 > #include <linux/netfilter_ipv4/ip_tproxy.h>
 >
350a353,464
 > forward_handle_tproxy (int fd, FwdState *fwdState)
 > {
 >     struct in_tproxy itp;
 >     int              itp_flags;
 >     struct in_addr   client_addr;
 >     struct in_addr   my_addr;
 >     struct in_addr   out_addr;
 >    
 >     debug(20, 2)("%s: client[%s][%d], proxy[%s][%d], my[%s][%d]\n",
 >                  __func__,
 >                  inet_ntoa(fwdState->request->client_addr),
 >                  ntohs(fwdState->request->client_port),
 >                  inet_ntoa(fwdState->request->xfwd_ip),
 >                  ntohs(fwdState->request->client_port),
 >                  inet_ntoa(fwdState->request->my_addr),
 >                  ntohs(fwdState->request->my_port));
 >    
 >    
 >     /*
 >      * If the client address as stored in the X-FORWARD field is a 
local address,
 >      * don't try to proxy.
 >      */
 >     client_addr.s_addr = ntohl(fwdState->request->xfwd_ip.s_addr);
 >     my_addr.s_addr = ntohl(fwdState->request->my_addr.s_addr);
 >     out_addr = getOutgoingAddr(fwdState->request);
 >     out_addr.s_addr = ntohl(out_addr.s_addr);
 >
 >     if (client_addr.s_addr == INADDR_ANY) {
 >         return;
 >     }
 >    
 >     if (client_addr.s_addr == INADDR_LOOPBACK) {
 >         return;
 >     }
 >
 >     if (client_addr.s_addr == my_addr.s_addr) {
 >         return;
 >     }
 >    
 >     if (client_addr.s_addr == out_addr.s_addr) {
 >         return;
 >     }
 >    
 >     /*
 >      * OK, it's safe to proxy for the client.
 >      */
 >     itp.itp_faddr.s_addr = fwdState->request->xfwd_ip.s_addr;
 >
 >     /*
 >      * On a connect, the port number is assigned by the system
 >      */
 >     itp.itp_fport = 0;
 >    
 >    
 >     /* If these syscalls fail then we just fallback to connecting
 >      * normally by simply ignoring the errors...
 >      */
 >    
 >     /*
 >      * We need to be superuser to set the proxy address.
 >      */
 >     enter_suid();
 >    
 >     /*
 >      * Register the client address we're interested in.
 >      */
 >         if (setsockopt(fd, SOL_IP, IP_TPROXY_ASSIGN, &itp, 
sizeof(itp)) == -1)
 >     {
 >         debug(20, 2)("%s: tproxy ip=%s, port=%d, ERROR ASSIGN: %s\n",
 >                      __func__,
 >                      inet_ntoa(itp.itp_faddr),
 >                      ntohs(itp.itp_fport), strerror(errno));
 >         /*
 >          * If this fails, don't try the proxy connect
 >          */
 >         leave_suid();
 >         return;
 >        
 >     } else {
 >         debug(20, 2)("%s: tproxy ip=%s,0x%x,port=%d TPROXY_ASSIGN\n",
 >                      __func__,
 >                      inet_ntoa(itp.itp_faddr),
 >                      ntohl(itp.itp_faddr.s_addr),
 >                      ntohs(itp.itp_fport));
 >     }
 >    
 >     /*
 >      * Set the socket up for an outgoing connect using
 >      * the client address.
 >      */
 >     itp_flags = ITP_CONNECT;
 >     if (setsockopt(fd, SOL_IP, IP_TPROXY_FLAGS, &itp_flags,
 >                    sizeof(itp_flags)) == -1)
 >     {
 >         debug(20, 2)("%s: tproxy ip=%x,port=%d, ERROR CONNECT: %s\n",
 >                      __func__,
 >                      ntohl(itp.itp_faddr.s_addr),
 >                      ntohs(itp.itp_fport), strerror(errno));
 >     } else {
 >         debug(20, 2)("%s: tproxy ip=%x,port=%d TPROXY_CONNECT\n",
 >                      __func__,
 >                      ntohl(itp.itp_faddr.s_addr),
 >                      ntohs(itp.itp_fport));
 >     }
 >
 >     /*
 >      * Back to previous user id
 >      */
 >     leave_suid();
 > }
 >
 > static void
363a478,485
 >     struct in_addr *local;
 >    
 >     if (Config.onoff.linux_tproxy) {
 >         local=&fwdState->src.sin_addr;
 >     } else {
 >         local = NULL;
 >     }
 >
386c508
<     if ((fd = pconnPop(host, port)) >= 0) {
---
 >     if ((fd = pconnPop(host, port, local)) >= 0) {
410,411c532,533
<     debug(17, 3) ("fwdConnectStart: got addr %s, tos %d\n",
<     inet_ntoa(outgoing), tos);
---
 >     debug(17, 3) ("%s: outgoing addr %s, tos %d\n",
 >                   __func__, inet_ntoa(outgoing), tos);
420c542
<     debug(50, 4) ("fwdConnectStart: %s\n", xstrerror());
---
 >     debug(50, 3) ("fwdConnectStart: %s\n", xstrerror());
446a569,580
 >
 >     switch (Config.onoff.linux_tproxy) {
 >     case 0:
 >         break;
 >     case 1:
 >         forward_handle_tproxy(fd, fwdState);
 >         break;
 >        
 >     default:
 >         break;
 >     }
 >    
Index: src/http.c
568a569,572
 >     struct in_addr *local;
 >
 >     local = NULL;
 >
577a582,586
 >
 >     if ( Config.onoff.linux_tproxy ) {
 >         local=&httpState->request->client_addr;
 >     }
 >
764c773
<             pconnPush(fd, request->host, request->port);
---
 >             pconnPush(fd, request->host, request->port, local);
Index: src/pconn.c
52d51
< static const char *pconnKey(const char *host, u_short port);
61,62c60,63
< static const char *
< pconnKey(const char *host, u_short port)
---
 > #define PCONN_KEYLEN (SQUIDHOSTNAMELEN + 24)
 >
 > static inline const int
 > pconnKey(char *buf, const char *peer, u_short port, struct in_addr 
*local)
64,66c65,70
<     LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN + 10);
<     snprintf(buf, SQUIDHOSTNAMELEN + 10, "%s.%d", host, (int) port);
<     return buf;
---
 >     if ( local == NULL ) {
 >         return snprintf(buf, PCONN_KEYLEN, "%s.%d", peer, (int) port);
 >     }else{
 >         return snprintf(buf, PCONN_KEYLEN, "%s.%d.%s",
 >         peer, (int) port, inet_ntoa(*local));
 >     }
187c191
< pconnPush(int fd, const char *host, u_short port)
---
 > pconnPush(int fd, const char *peer, u_short port, struct in_addr *local)
191c195
<     LOCAL_ARRAY(char, key, SQUIDHOSTNAMELEN + 10);
---
 >     LOCAL_ARRAY(char, key, PCONN_KEYLEN);
202c206
<     strcpy(key, pconnKey(host, port));
---
 >     pconnKey(key, peer, port, local);
220c224
<     snprintf(desc, FD_DESC_SZ, "%s idle connection", host);
---
 >     snprintf(desc, FD_DESC_SZ, "%s idle connection", peer);
226c230
< pconnPop(const char *host, u_short port)
---
 > pconnPop(const char *peer, u_short port, struct in_addr *local)
231c235
<     LOCAL_ARRAY(char, key, SQUIDHOSTNAMELEN + 10);
---
 >     LOCAL_ARRAY(char, key, PCONN_KEYLEN);
233c237
<     strcpy(key, pconnKey(host, port));
---
 >     pconnKey(key, peer, port, local);
Index: src/protos.h
1140,1141c1140,1141
< extern void pconnPush(int, const char *host, u_short port);
< extern int pconnPop(const char *host, u_short port);
---
 > extern void pconnPush(int, const char *peer, u_short port, struct 
in_addr *local);
 > extern int pconnPop(const char *peer, u_short port, struct in_addr 
*local);
Index: src/structs.h
610a611,613
 > #if LINUX_NETFILTER
 >         int linux_tproxy;
 > #endif
1659a1663
 >     in_port_t client_port;
1677a1682,1686
 >     /*
 >      * The client IP addresses from the X-Forwarded-For field in the
 >      * request header.
 >      */
 >     struct in_addr xfwd_ip;
1994a2004,2006
 > #if LINUX_NETFILTER
 >     struct sockaddr_in src;
 > #endif
Received on Tue Oct 25 2005 - 13:33:30 MDT
This archive was generated by hypermail pre-2.1.9 : Tue Nov 01 2005 - 12:00:07 MST