Re: [squid-users] tproxy2 patch for squid3

From: Henrik Nordstrom <henrik@dont-contact.us>
Date: Sat, 29 Jul 2006 15:28:35 +0200

lör 2006-07-29 klockan 09:44 +0200 skrev Jan Engelhardt:
> Hello,
>
>
> Regular client-side transparent proxying is easily accomplished by
> redirecting network traffic using -j DNAT, -j REDIRECT, or -j TPROXY (I do
> not know why this seems needed). However, server-side transparency requires
> a little more kick.
> https://lists.balabit.hu/pipermail/tproxy/2006-July/000273.html
>
> This patch actually brew in my homemade version of squid3 and worked long
> before tproxy even hit the squid2.6 scene. CAP_NET_ADMIN must be accounted for
> by the user, and in my case, is easily done through the MultiAdmin linux kernel
> module.

Comments:

Your patch does not handle persistent connections. If there is multiple
clients talking to the same server their requests may get intermixed, no
longer keeping the source IP binding.

Why the commConnectStart2 function instead of extending
commConnectStart?

Regards
Henrik

>
> diff --fast -Ndpru squid-3.0.PRE4-20060727~/src/cf.data.pre squid-3.0.PRE4-20060727/src/cf.data.pre
> --- squid-3.0.PRE4-20060727~/src/cf.data.pre 2006-07-02 18:53:46.000000000 +0200
> +++ squid-3.0.PRE4-20060727/src/cf.data.pre 2006-07-28 15:56:59.629577000 +0200
> @@ -2852,6 +2852,16 @@ DOC_START
> the correct result.
> DOC_END
>
> +NAME: tproxy
> +TYPE: onoff
> +DEFAULT: off
> +LOC: Config.onoff.tproxy
> +DOC_START
> + If you have Linux with iptables and TPROXY2 support, you can enable
> + this option to have SQUID make outgoing connections using the original
> + IP address of the client.
> +DOC_END
> +
> NAME: tcp_outgoing_tos tcp_outgoing_ds tcp_outgoing_dscp
> TYPE: acl_tos
> DEFAULT: none
> diff --fast -Ndpru squid-3.0.PRE4-20060727~/src/comm.cc squid-3.0.PRE4-20060727/src/comm.cc
> --- squid-3.0.PRE4-20060727~/src/comm.cc 2006-05-30 23:15:58.000000000 +0200
> +++ squid-3.0.PRE4-20060727/src/comm.cc 2006-07-28 15:57:02.299577000 +0200
> @@ -39,8 +39,10 @@
> #include "StoreIOBuffer.h"
> #include "comm.h"
> #include "fde.h"
> +#include "forward.h"
> #include "CommIO.h"
> #include "ConnectionDetail.h"
> +#include "HttpRequest.h"
> #include "MemBuf.h"
> #include "pconn.h"
> #include "SquidTime.h"
> @@ -52,6 +54,7 @@
> #include <netinet/tcp.h>
> #endif
>
> +#include "ip_tproxy.h"
>
> class ConnectStateData
> {
> @@ -66,7 +69,7 @@ public:
> char *host;
> u_short port;
>
> - struct sockaddr_in S;
> + struct sockaddr_in S, src_addr;
> CallBack<CNCB> callback;
>
> struct IN_ADDR in_addr;
> @@ -1150,6 +1153,26 @@ ConnectStateData::operator delete (void
> cbdataFree(address);
> }
>
> +void commConnectStart2(int fd, const char *host, u_short port, CNCB *callback,
> + FwdState *fs)
> +{
> + ConnectStateData *cs;
> +
> + cs = new ConnectStateData;
> + cs->fd = fd;
> + cs->host = xstrdup(host);
> + cs->port = port;
> + cs->callback = CallBack<CNCB>(callback, fs);
> + if(fs->request != NULL) {
> + cs->src_addr.sin_addr = fs->request->client_addr;
> + cs->src_addr.sin_port = htons(fs->request->client_port);
> + } else {
> + memset(&cs->src_addr, 0, sizeof(cs->src_addr));
> + }
> + comm_add_close_handler(fd, commConnectFree, cs);
> + ipcache_nbgethostbyname(host, commConnectDnsHandle, cs);
> +}
> +
> void
> commConnectStart(int fd, const char *host, u_short port, CNCB * callback, void *data)
> {
> @@ -1353,7 +1376,7 @@ ConnectStateData::connect()
> if (S.sin_addr.s_addr == 0)
> defaults();
>
> - switch (comm_connect_addr(fd, &S)) {
> + switch (comm_connect_addr(fd, &S, &src_addr)) {
>
> case COMM_INPROGRESS:
> debug(5, 5) ("ConnectStateData::connect: FD %d: COMM_INPROGRESS\n", fd);
> @@ -1406,9 +1429,45 @@ commSetTimeout(int fd, int timeout, PF *
> return F->timeout;
> }
>
> -int
> +static void do_tproxy(int sock, const struct sockaddr_in *src,
> + const struct sockaddr_in *dest)
> +{
> + struct in_tproxy itp;
> + int ret;
>
> -comm_connect_addr(int sock, const struct sockaddr_in *address)
> + memset(&itp, 0, sizeof(itp));
> + itp.v.addr.faddr = src->sin_addr; // fix endianness
> + itp.v.addr.fport = 0; //src->sin_port;
> + itp.op = TPROXY_ASSIGN;
> +
> + if((ret = setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp))) != 0) {
> + debug(5, 3) ("setsockopt IP_TPROXY/TPROXY_ASSIGN failed\n");
> + return;
> + }
> +
> + memset(&itp, 0, sizeof(itp));
> + itp.v.addr.faddr = dest->sin_addr;
> + itp.v.addr.fport = dest->sin_port;
> + itp.op = TPROXY_CONNECT;
> + if((ret = setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp))) != 0) {
> + debug(5, 3) ("setsockopt IP_TPROXY/TPROXY_CONNECT failed\n");
> + return;
> + }
> +
> + memset(&itp, 0, sizeof(itp));
> + itp.v.flags = ITP_CONNECT;
> + itp.op = TPROXY_FLAGS;
> + if((ret = setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp))) != 0) {
> + debug(5, 3) ("setsockopt IP_TPROXY/TPROXY_FLAGS failed\n");
> + return;
> + }
> +
> + return;
> +}
> +
> +int
> +comm_connect_addr(int sock, const struct sockaddr_in *address,
> + const struct sockaddr_in *src)
> {
> comm_err_t status = COMM_OK;
> fde *F = &fd_table[sock];
> @@ -1425,6 +1484,10 @@ comm_connect_addr(int sock, const struct
> F->flags.called_connect = 1;
> statCounter.syscalls.sock.connects++;
>
> + if(Config.onoff.tproxy && src != NULL && src->sin_addr.s_addr != 0 &&
> + ((ntohl(src->sin_addr.s_addr) >> 24) & 0xFF) != 0x7F)
> + do_tproxy(sock, src, address);
> +
> x = connect(sock, (struct sockaddr *) address, sizeof(*address));
>
> if (x < 0)
> diff --fast -Ndpru squid-3.0.PRE4-20060727~/src/forward.cc squid-3.0.PRE4-20060727/src/forward.cc
> --- squid-3.0.PRE4-20060727~/src/forward.cc 2006-06-20 00:49:59.000000000 +0200
> +++ squid-3.0.PRE4-20060727/src/forward.cc 2006-07-28 15:56:59.629577000 +0200
> @@ -811,7 +811,7 @@ FwdState::connectStart()
> else
> hierarchyNote(&request->hier, fs->code, request->host);
>
> - commConnectStart(fd, host, port, fwdConnectDoneWrapper, this);
> + commConnectStart2(fd, host, port, fwdConnectDoneWrapper, this);
> }
>
> void
> diff --fast -Ndpru squid-3.0.PRE4-20060727~/src/ip_tproxy.h squid-3.0.PRE4-20060727/src/ip_tproxy.h
> --- squid-3.0.PRE4-20060727~/src/ip_tproxy.h 1970-01-01 01:00:00.000000000 +0100
> +++ squid-3.0.PRE4-20060727/src/ip_tproxy.h 2006-07-28 15:56:59.639577000 +0200
> @@ -0,0 +1,78 @@
> +/*
> + * Transparent proxy support for Linux/iptables
> + *
> + * Copyright (c) 2002-2004 BalaBit IT Ltd.
> + * Author: Balzs Scheidler
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#ifndef _IP_TPROXY_H
> +#define _IP_TPROXY_H
> +
> +#ifdef __KERNEL__
> +#include <linux/types.h>
> +#include <linux/in.h>
> +#else
> +#include <netinet/in.h>
> +#ifndef IP_RECVORIGADDRS
> +#define IP_RECVORIGADDRS 11273
> +#define IP_ORIGADDRS IP_RECVORIGADDRS
> +struct in_origaddrs {
> + struct in_addr ioa_srcaddr;
> + struct in_addr ioa_dstaddr;
> + unsigned short int ioa_srcport;
> + unsigned short int ioa_dstport;
> +};
> +#endif
> +#endif
> +
> +/*
> + * used in setsockopt(SOL_IP, IP_TPROXY) should not collide
> + * with values in <linux/in.h>
> + */
> +
> +#define IP_TPROXY 11274
> +
> +/* tproxy operations */
> +enum {
> + TPROXY_VERSION = 0,
> + TPROXY_ASSIGN,
> + TPROXY_UNASSIGN,
> + TPROXY_QUERY,
> + TPROXY_FLAGS,
> + TPROXY_ALLOC,
> + TPROXY_CONNECT
> +};
> +
> +/* bitfields in IP_TPROXY_FLAGS */
> +#define ITP_CONNECT 0x00000001
> +#define ITP_LISTEN 0x00000002
> +#define ITP_ESTABLISHED 0x00000004
> +
> +#define ITP_ONCE 0x00010000
> +#define ITP_MARK 0x00020000
> +#define ITP_APPLIED 0x00040000
> +#define ITP_UNIDIR 0x00080000
> +
> +struct in_tproxy_addr{
> + struct in_addr faddr;
> + u_int16_t fport;
> +};
> +
> +struct in_tproxy {
> + /* fixed part, should not change between versions */
> + u_int32_t op;
> + /* extensible part */
> + union _in_args {
> + u_int32_t version;
> + struct in_tproxy_addr addr;
> + u_int32_t flags;
> + } v;
> +};
> +
> +#endif
> +
> diff --fast -Ndpru squid-3.0.PRE4-20060727~/src/protos.h squid-3.0.PRE4-20060727/src/protos.h
> --- squid-3.0.PRE4-20060727~/src/protos.h 2006-07-02 18:53:46.000000000 +0200
> +++ squid-3.0.PRE4-20060727/src/protos.h 2006-07-28 15:57:02.299577000 +0200
> @@ -132,8 +132,10 @@ SQUIDCEXTERN void comm_reset_close(int f
> SQUIDCEXTERN void comm_lingering_close(int fd);
> #endif
> SQUIDCEXTERN void commConnectStart(int fd, const char *, u_short, CNCB *, void *);
> +class FwdState;
> +SQUIDCEXTERN void commConnectStart2(int, const char *, u_short, CNCB *, FwdState *);
>
> -SQUIDCEXTERN int comm_connect_addr(int sock, const struct sockaddr_in *);
> +SQUIDCEXTERN int comm_connect_addr(int sock, const struct sockaddr_in *, const struct sockaddr_in * = NULL);
> SQUIDCEXTERN void comm_init(void);
>
> SQUIDCEXTERN int comm_open(int, int, struct IN_ADDR, u_short port, int, const char *note);
> @@ -256,7 +258,6 @@ SQUIDCEXTERN void fqdncache_restart(void
> SQUIDCEXTERN EVH fqdncache_purgelru;
> SQUIDCEXTERN void fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames);
>
> -class FwdState;
> SQUIDCEXTERN void ftpStart(FwdState *);
> SQUIDCEXTERN char *ftpUrlWith2f(const HttpRequest *);
>
> diff --fast -Ndpru squid-3.0.PRE4-20060727~/src/structs.h squid-3.0.PRE4-20060727/src/structs.h
> --- squid-3.0.PRE4-20060727~/src/structs.h 2006-07-02 18:53:47.000000000 +0200
> +++ squid-3.0.PRE4-20060727/src/structs.h 2006-07-28 15:57:02.309577000 +0200
> @@ -559,6 +559,7 @@ struct _SquidConfig
> int emailErrData;
> int httpd_suppress_version_string;
> int global_internal_static;
> + int tproxy;
> }
>
> onoff;
> #<<eof>>
>
> Jan Engelhardt

Received on Sat Jul 29 2006 - 07:28:39 MDT

This archive was generated by hypermail pre-2.1.9 : Tue Aug 01 2006 - 12:00:02 MDT