Re: Patches

From: Ken Moberg <sf@dont-contact.us>
Date: Mon, 24 Oct 2005 13:20:40 -0700

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