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; > #endifReceived 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