Transparent proxy

Transparent proxy

Post by Lars Bensma » Fri, 30 Oct 1998 04:00:00



Hi,

I got a question concerning the transparent proxy support in the Linux
kernel.

As I understand it the Linux box will catch any outgoing request to a
specific port and redirect it to a local port. (If you set it up correctly
with ipfwadm).

Now if I write a proxy application on the Linux machine that will accept
these redirected requests, can it somehow inquire where the orignal
request was going?

To make it a little clearer, here is a small graph:

+-------------+            +-------------+
+Remote host 1+            +Remote host 2+
+-------------+            +-------------+
            \               /
             \             /
              +-----------+
              +Linux host +
              +with transp+
              +proxy      +
              +-----------+
                    |
                    |
              +-----------+
              +Client     +
              +maschine   +
              +-----------+

OK, my client machine tries to connect to remote host 1 on port xyz. Linux
catches the request and forwards it to a local port where a proxy is
listening. Does this process know, if I was trying to reach remote host 1 or
2 (or any other machine)?

Thanks for your help,
Lars

P.S. Are there any more infos regarding this feature? There are 5 lines or
so in the ipfwadm manpage, but I couldn't find anything else.

--
Most people have two reasons for doing anything -- a good reason, and
the real reason.

 
 
 

Transparent proxy

Post by Lars Hofhans » Sat, 31 Oct 1998 04:00:00


Hi,


> I got a question concerning the transparent proxy support in the Linux
> kernel.

> As I understand it the Linux box will catch any outgoing request to a
> specific port and redirect it to a local port. (If you set it up correctly
> with ipfwadm).

It will intercept each _incoming_ request. I guess that's
what you meant...

Quote:

> Now if I write a proxy application on the Linux machine that will accept
> these redirected requests, can it somehow inquire where the orignal
> request was going?

For TCP connections you can use the getsockname(...) call
to get the address and port of the "client" socket
(the one returned by the accept call).

Here's a little code fragment:
------

int client,server;
struct sockaddr_in in_addr,proxy_addr;

client = accept( server, &in_addr, &len );
getsockname( client, (struct sockaddr*)&proxy_addr, &len );

/* here in_addr will contain the source address, and
   proxy_addr will contain the _original_ destination
   address */

I didn't try anything for UDP, yet.

Cheers,

        Lars

--
Legal Warning: Anyone sending me unsolicited/commercial email
WILL be charged a $100 proof-reading fee. See US Code Title 47,
Sec.227(a)(2)(B), Sec.227(b)(1)(C) and Sec.227(b)(3)(C).

 
 
 

Transparent proxy

Post by Lars Bensma » Sun, 01 Nov 1998 04:00:00


Hi,

On Fri, 30 Oct 1998 18:46:51 +0100, Lars Hofhansl



>> I got a question concerning the transparent proxy support in the Linux
>> kernel.

>> Now if I write a proxy application on the Linux machine that will accept
>> these redirected requests, can it somehow inquire where the orignal
>> request was going?

>For TCP connections you can use the getsockname(...) call
>to get the address and port of the "client" socket
>(the one returned by the accept call).

>Here's a little code fragment:
>------
[snip]

>I didn't try anything for UDP, yet.

Thanks for the info. It works great for TCP, but unfortunately it doesn't
work well for UDP. When I call getsockname() for a UDP-Socket, it gives me
the destination port-number, but the destination address is set to 0.0.0.0.
That doesn't really help me, where to forward the packet :-)

Is there any way to get the destination address for an intercepted
UDP-Paket?

cu,
Lars

--
A billion here, a billion there -- pretty soon it adds up to real money.
                -- Sen. Everett Dirksen, on the U.S. defense budget

 
 
 

Transparent proxy

Post by Andi Klee » Sun, 01 Nov 1998 04:00:00




> Hi,
> On Fri, 30 Oct 1998 18:46:51 +0100, Lars Hofhansl


>>> I got a question concerning the transparent proxy support in the Linux
>>> kernel.

>>> Now if I write a proxy application on the Linux machine that will accept
>>> these redirected requests, can it somehow inquire where the orignal
>>> request was going?

>> For TCP connections you can use the getsockname(...) call
>> to get the address and port of the "client" socket
>> (the one returned by the accept call).

>> Here's a little code fragment:
>> ------
> [snip]

>> I didn't try anything for UDP, yet.
> Thanks for the info. It works great for TCP, but unfortunately it doesn't
> work well for UDP. When I call getsockname() for a UDP-Socket, it gives me
> the destination port-number, but the destination address is set to 0.0.0.0.
> That doesn't really help me, where to forward the packet :-)
> Is there any way to get the destination address for an intercepted
> UDP-Paket?

Linux uses a very very ugly hack to do that. The real destination address
is put into the part of the generic struct sockaddr that is not used by
IPv4 addresses.

So use something like this:
                struct sockaddr adr;
                struct sockaddr_in *locaddr, *dstaddr;

                getsockname(proxy_sk, &adr, sizeof(struct sockaddr_in));
                locaddr = (struct sockaddr_in *) (&adr);
                dstaddr = (struct sockaddr_in *) (&adr.sin_zero);

The information you want is in *dstaddr know.

I warned you - it is ugly ;)

-Andi

 
 
 

Transparent proxy

Post by Lars Bensma » Sun, 01 Nov 1998 04:00:00




>Linux uses a very very ugly hack to do that. The real destination address
>is put into the part of the generic struct sockaddr that is not used by
>IPv4 addresses.

>So use something like this:
>               struct sockaddr adr;
>               struct sockaddr_in *locaddr, *dstaddr;

>               getsockname(proxy_sk, &adr, sizeof(struct sockaddr_in));
>               locaddr = (struct sockaddr_in *) (&adr);
>               dstaddr = (struct sockaddr_in *) (&adr.sin_zero);

>The information you want is in *dstaddr know.

>I warned you - it is ugly ;)

Besides being ugly, I can't get it to work :-).

I started my de* and looked at the memory pointed to by *locaddr and
couldn't find anything near the source address in the next 16 bytes
(sizeof(sockaddr_in)).

And the line 'dstaddr = (struct sockaddr_in *) (&adr.sin_zero);' doesn't
compile. I changed it to
dstaddr = (struct sockaddr_in *) (locaddr->sin_zero);
I hope, this is what you meant.
But I really can't find any useful information there.

cu,
Lars

--
Why Windows NT Server 4.0 continues to exist in the enterprise would
be a topic appropriate for an investigative report in the field of
psychology or marketing, not an article on information technology.
 (John Kirch - www.kirch.net)