Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jan 2000 13:53:01 -0500 (EST)
From:      Robert Watson <robert@cyrus.watson.org>
To:        mouss <usebsd@free.fr>
Cc:        freebsd-ipfw@freebsd.org
Subject:   RE: Two-way transparency
Message-ID:  <Pine.BSF.3.96.1000118134044.2527D-100000@fledge.watson.org>
In-Reply-To: <NDBBJDFPGLMLFHLNEEOMIEDODKAA.usebsd@free.fr>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 17 Jan 2000, mouss wrote:

> This is easily done by making the proxy to bind() its client socket
> to the address of the original client, before calling connect() and
> in the case of unconnected sokets, before calling any send() function.
> 
> more precisely, a proxy will have two socket descriptors:
> 	client_fd: socket used between client and proxy
> 	server_fd: socket between proxy and remote server.
> 
> a getpeername(client_fd, ...) yieds the IP address of the client (among
> other things).
> store this in a struct sockaddr variable "client_addr". Then just call
> 
> 	error = bind(remote_fd, &client_addr, client_addr_len);
> 	if (error < 0) {
> 		unhappy("cannot bind it....");
> 	}
> 
> This makes the proxy uses the IP client address as its "outgoing" address.
> This works because the TCP/IP stack doesn't normally check that the address
> you bind to is local or not.

I seem to get 

  bind: Can't assign requested address
 
When trying what you suggest--it could be that I'm doing it wrong, or it
could be that there is actually a test to check for a valid client IP.
This code from netinet/in_pcb.c suggests that there is such a check, at
lest in 3.4-STABLE:

                } else if (sin->sin_addr.s_addr != INADDR_ANY) {
                        sin->sin_port = 0;              /* yech... */
                        if (ifa_ifwithaddr((struct sockaddr *)sin) == 0)
                                return (EADDRNOTAVAIL);

I.e., if there is no interface hosting the given address, then reject the
address.  This is after a check for multicast addresses...  I haven't read
the divert code in detail, so don't know how that might impact things.

> There are three notes here:
> 
> 1- you can't force the arbitrary source port to that of the client, since
> the port is not necessarily free
> on the gateway host. anyway, there's no reason to force an arbitrary port!

I would have thought it would be possible given that, if the client uses
(clientIP,port) then it knows it is unique, meaning that we should also
have no existing binding for (clientIP,port) on the firewall box.  My
understanding was that on a given box (*,port) didn't have to be available
just (mychoiceIP,port).

> 2- You'll have to check your packet filter config carefully to make sure
> that responses to proxy packets
> will be returned to the proxy! Indeed, since you're using the client IP
> address to send packets, responses will
> be directed to the client. you then have to divert these responses to the
> proxy and make sure there is no
> other route to the client. otherwise, you'll end with "dangling
> connections"!

I'm not clear on what you mean--to what extent, based on the tcp
connection block configured using bind, will the kernel know to "just do
the right thing"?  Will I need to add an ipfw fwd entry to force packets
to the right place come from the target host via the proxy?

> 3- Under Solaris (this doesn't concern BSD but is worth to be noted), if you
> call rresvport() to use a
> reserved port, then the bind() above will fail. I am not sure if this was
> bug and whether it has been fixed, but an easy
> workaround is to copy the BSD version of rresvport() and call it instead of
> that of the system.
> 
> 
> While I am in, I am in the process of writing new proxies (with the above
> functionality and other functionalities
> as well). The fwtk is getting old and NAI are MS-oriented. I am planning to
> implement this in C (but I am
> open to using C++ instead, if there are enough arguments) and have many
> ideas in mind. Are there any volounteers?

Unfortunately time and work prohibit my becoming seriously involved in
such a project at this time :-).

> 
> 
> Regards,
> 
> mouss
> 
> 
> 
> > -----Original Message-----
> > From: owner-freebsd-ipfw@FreeBSD.ORG
> > [mailto:owner-freebsd-ipfw@FreeBSD.ORG]On Behalf Of Robert Watson
> > Sent: Friday, January 07, 2000 2:45 PM
> > To: freebsd-ipfw@freebsd.org
> > Subject: Two-way transparency
> >
> >
> >
> > Last night at the fug-washdc meeting, we discussed expansions to ipfw that
> > might be useful--not doubt someone will post a summary soon.  One of the
> > issues I raised and am interested in is the ability to have userland
> > proxies filter traffic in a completely transparent way -- i.e., two way
> > transparency.  Right now with NAT and divert sockets, fwds, etc, it's easy
> > to do transparency from the perspective of a client application *making* a
> > connection, but I'm not sure how to go about allowing the proxy to go
> > about making an outgoing connection that appears to come from the client.
> >
> > There are a number of applications where this would be useful, including
> > transparent local firewalls on multi-user machines, filtering incoming
> > connections, firewalls for protocols that bind address information into
> > their connections, etc.  It would allow a userland proxy-based firewall
> > (such as fwtk, etc) to look more like a traditional packet filter not
> > running with NAT.
> >
> > Anyone have any thoughts on this? :-)
> >
> >   Robert N M Watson
> >
> > robert@fledge.watson.org              http://www.watson.org/~robert/
> > PGP key fingerprint: AF B5 5F FF A6 4A 79 37  ED 5F 55 E9 58 04 6A B1
> > TIS Labs at Network Associates, Safeport Network Services
> >
> >
> >
> > To Unsubscribe: send mail to majordomo@FreeBSD.org
> > with "unsubscribe freebsd-ipfw" in the body of the message
> >
> 
> 


  Robert N M Watson 

robert@fledge.watson.org              http://www.watson.org/~robert/
PGP key fingerprint: AF B5 5F FF A6 4A 79 37  ED 5F 55 E9 58 04 6A B1
TIS Labs at Network Associates, Safeport Network Services



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ipfw" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.1000118134044.2527D-100000>