Hi there,
We have a transparent TCP proxy application for Linux (with epoll) which I ported to FreeBSD (with kqueue).
This is just a test application which transparently accepts a TCP connection from a peer, gets its source/destination ip-port and makes a connection from the same source to the same destination and after that just relay the traffic.
On Linux the acceptor socket needs to be setup with
so that the destination ip-port can be later retrieved from the accepted socket simply using
The above test setup works fine on Linux. Now I'm trying to do the same thing on FreeBSD using
I tried to redirect the incoming connections with the following rule:
The problem is that I received the socket in the application with destination 127.0.0.1:8081 instead of the original destination. I checked with the pflog and saw that the rule itself seems to change the desitnation
Later I tried using
and I saw the rule matching in the pflog
but I didn't receive any socket in the application.
So my question are:
1. Is there a way to transparently redirect packets to a given socket using PF?
2. If this can't be done with PF, can it be done with IPFW?
3. Can you give me some example of firewall which would do the thing like the Linux firewall above?
Thanks,
Pavel.
We have a transparent TCP proxy application for Linux (with epoll) which I ported to FreeBSD (with kqueue).
This is just a test application which transparently accepts a TCP connection from a peer, gets its source/destination ip-port and makes a connection from the same source to the same destination and after that just relay the traffic.
On Linux the acceptor socket needs to be setup with
C:
setsockopt(sk, IPPROTO_IP, IP_TRANSPARENT)
getsockname
. The outgoing socket also needs to use IP_TRANSPARENT
in order to be able to bind to non local ip-port. The iptables rules needed for this proxy to work are something like:
Code:
-A PREROUTING -p tcp -m socket -j DIVERT # If there is an opened socket for a packet send the packet to it
-A PREROUTING -i -p tcp --dport 80 -j TPROXY --on-port <port> --on-ip <ip> --tproxy-mark <mark> # Redirects all packets not consumed by the above rule to the transparent listener. Usually the first SYN and the 3rd ACK from the 3 way handshake
-A DIVERT -j MARK --set-xmark <mark>
-A DIVERT -j ACCEPT
IP_BINDANY
and PF firewall.I tried to redirect the incoming connections with the following rule:
rdr log on em2 inet proto tcp from any to any port 80 -> (lo0) port 8080
The problem is that I received the socket in the application with destination 127.0.0.1:8081 instead of the original destination. I checked with the pflog and saw that the rule itself seems to change the desitnation
18:37:58.823472 rule 0/0(match): rdr in on em2: 10.20.30.1.37873 > 127.0.0.1.8081: Flags [S], seq 367059445, win 64240, options [mss 1460,sackOK,TS val 2607264902 ecr 0,nop,wscale 7], length 0
Later I tried using
divert-to
hoping that it'll do the job for transparent redirection:pass in log on em2 inet proto tcp from any to any port 80 divert-to localhost port 8081
and I saw the rule matching in the pflog
18:45:04.611782 rule 0/0(match): pass in on em2: 10.20.30.1.44767 > 195.85.215.215.80: Flags [S], seq 3676405420, win 64240, options [mss 1460,sackOK,TS val 2607690690 ecr 0,nop,wscale 7], length 0
but I didn't receive any socket in the application.
So my question are:
1. Is there a way to transparently redirect packets to a given socket using PF?
2. If this can't be done with PF, can it be done with IPFW?
3. Can you give me some example of firewall which would do the thing like the Linux firewall above?
Thanks,
Pavel.