Hi, I agree that the "transparent" keyword is not really documented.
The "transparent" keyword enables the use of the SO_BINDANY socket option that was added a few releases ago. It is an option for relays to use the IP address of the client as the source of the forwarded connection instead of the local gateway IP address of the relayd machine. A relay uses two socket connections a) a server socket that is connected to the client and b) a client socket that is connected to the target server. SO_BINDANY is an option on b) that allows to bind(2) the source address to a non-local IP address, to the source address of a) in this case. It is not directly related to the way of accepting connections on a) and it doesn't really matter if it is via rdr-to, divert-to or a direct listener on a public IP address. >From the manpage setsockopt(2): SO_BINDANY allows the socket to be bound to addresses which are not local to the machine, so it can be used to make a transparent proxy. Note that this option is limited to the super-user. In order to receive packets for these addresses, SO_BINDANY needs to be combined with matching outgoing pf(4) divert rules. For example, with the following rule the socket receives packets for 192.168.0.10 even if it is not a local address: pass out inet from 192.168.0.10 divert-reply Here is a little ASCII art: 10.0.0.2 ix0: 10.0.0.1 ix1: 192.168.1.1 192.168.1.100 +--------+ +--------+ +--------+ | Client |---------------------| relayd |---------------------| Server | +--------+ +--------+ +--------+ | a) 10.0.0.2->10.0.0.1 || b) 10.0.0.2->192.168.1.100 | |---------------------------->||----------------------------->| || Without transparent mode b) would be 192.168.1.1->192.168.1.100. For the return traffic it is important that the server 192.168.1.100 knows about the 10.0.0.0/8 network and that it sends any replies back via the gateway 10.0.0.1 - so it doesn't make sense with NAT. The gateway that is running relayd and pf will know about the return traffic to 10.0.0.2 and and receives it locally instead of forwarding it to the internal host because of the pf state that was entered by the divert-reply rule. You can also run transparent SSL acceleration this way: a) with SSL, b) with plain TCP but coming from the original client IP. You can simply test divert-reply on any gateway that is running pf using the nc(1) tool. Our "netcat" is trying to use SO_BINDANY by default if you're binding the source to a non-local address as root. A simplified example that could be run on the gateway above: # echo "pass out on ix1 from 10.0.0.2 divert-reply" >> /etc/pf.conf # pfctl -f /etc/pf.conf # nc -s 10.0.0.2 192.168.1.100 22 Ok, now back to relayd. As I mentioned before it does not really matter how the traffic got into relayd. The are different possible examples to use transparent mode: 1) A normal listener on an IP address that is directly reachable by clients: relayd.conf: relay transfwd { listen on 10.0.0.1 port 25 transparent forward to <mail_servers> port smtp check tcp interface ix1 } pf.conf: pass out on ix1 to <mail_servers> divert-reply 2) A transparent proxy using rdr-to: relayd.conf: relay transrdrproxy { listen on 127.0.0.1 port 2525 transparent forward to nat lookup port smtp check tcp interface ix1 } pf.conf: pass in on ix1 proto tcp to port 25 rdr-to 127.0.0.1 port 2525 pass out on ix1 divert-reply 3) A transparent proxy using divert-to: relayd.conf: relay transdivertproxy { listen on 127.0.0.1 port 2525 transparent forward to destination port smtp check tcp interface ix1 } pf.conf: pass in on ix1 proto tcp to port 25 divert-to 127.0.0.1 port 2525 pass out on ix1 divert-reply Note: 2) divert-to is preferred over 3) rdr-to and support for nat lookups with 3) will probably go away in the future. OK... now the big question: why do we have to specify the "interface ix1" with the transparent keyword? Answer: the grammar requires it, but it is currently not used in the code! The reason for the mandatory "interface" keyword was that I intended to inject the divert-reply rule in the relayd/* anchor automatically but I didn't implement this yet. So you should specify the interface of the outgoing connection here and hope that I implement it some day... btw.: I'm currently cleaning up the relayd code before I move forward to implement and fix some outstanding things in relayd. Please have a look at the large diff that I sent to tech@ yesterday which needs testers. No new features, just to make sure if this diff doesn't break any existing setups! Reyk On Sat, May 07, 2011 at 11:49:48AM +0000, Stuart Henderson wrote: > Derek Buttineau <derek <at> csolve.net> writes: > > I'm attempting to setup a reverse proxy using relayd using the > > transparent forward to configuration (non-transparent works fine) > > under OpenBSD 4.4. > > Following up to an old mail...but since nobody has ever posted how > to get this working I imagine pretty much everyone who tried it is > confused :-) > > This bit is fine: > > > relay maildelivery { > > listen on $relayd_addr port 2525 > > protocol "tcp_service" > > transparent forward to <pop3_servers> port smtp check tcp interface > > bnx1 > > } > > ("interface XX" is not yet documented but it is needed > for "transparent forward"). > > Here is the problem: > > > rdr on $ext_if proto tcp from $netguard to 66.159.112.123 port smtp -> > > lo0 port 2525 > > Thanks to phessler for the clue; this must be done > with a divert-to rule. > > So, with modern PF syntax: > > pass in quick on $ext_if inet proto tcp from $netguard to \ > 66.159.112.123 port smtp divert-to lo0 port 2525 > > I'll try and come up with something for the docs.