tproxy routing issue within processes in the same machine
tproxy has problem working within 2 processes on the same machine, ie a client process using tproxy to spoof an IP, has problem communicating with the server process within the same machine. It seems tproxy attaches itself to mangle table PREROUTING chain, that is unable to hook to the in-machine process. I figured that for it to work, in this case, it needs to be able to attach itself to the INPUT chain. However that hook is not supported. Is there a way to get around this problem ?
Hi, IIRC it doesn't work for local connections/sockets, as it can't reroute outgoing packets to the local interface. On Sun, 2012-07-29 at 06:30 -0700, Ming-Ching Tiew wrote:
tproxy has problem working within 2 processes on the same machine, ie a client process using tproxy to spoof an IP, has problem communicating with the server process within the same machine.
It seems tproxy attaches itself to mangle table PREROUTING chain, that is unable to hook to the in-machine process. I figured that for it to work, in this case, it needs to be able to attach itself to the INPUT chain. However that hook is not supported.
Is there a way to get around this problem ?
-- Bazsi
Hello, AFAIK it is possible. 1. You have to bind new (spoofed) connection's port in certain range (e.g. 5000 - 10000, not ephemeral port range). 2. Setup rule to forward all outgoing TCP packets to ports in that range to localhost 3. Make connections to physical, not loopback address. I have it running on production for about 2 months now. Iptables rules and routes: ip rule add fwmark 1 lookup 100 ip route add local 0.0.0.0/0 dev lo table 100 iptables -t mangle -N DIVERT iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT iptables -t mangle -A DIVERT -j MARK --set-mark 1 iptables -t mangle -A DIVERT -j ACCEPT iptables -t mangle -A OUTPUT -p tcp --dport 5000:9999 -j MARK --set-mark 1 Example python code to create spoofed connection: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_IP, 19, 1) # IP_TRANSPARENT, not available in python's stdlib s.bind(('1.2.3.4', 5001)) s.connect(('192.168.1.9', 1234)) # connection always to physical interface address! I do free port management by myself, but you can do bind() in a loop. Best Regards, Karol Pilat W dniu 18.09.2012 10:04, Balazs Scheidler pisze:
Hi,
IIRC it doesn't work for local connections/sockets, as it can't reroute outgoing packets to the local interface.
On Sun, 2012-07-29 at 06:30 -0700, Ming-Ching Tiew wrote:
tproxy has problem working within 2 processes on the same machine, ie a client process using tproxy to spoof an IP, has problem communicating with the server process within the same machine.
It seems tproxy attaches itself to mangle table PREROUTING chain, that is unable to hook to the in-machine process. I figured that for it to work, in this case, it needs to be able to attach itself to the INPUT chain. However that hook is not supported.
Is there a way to get around this problem ?
--- On Tue, 9/18/12, Karol Piłat <cubix@vitresoft.com> wrote:
From: Karol Piłat <cubix@vitresoft.com> Subject: Re: [tproxy] tproxy routing issue within processes in the same machine To: "Balazs Scheidler" <bazsi@balabit.hu> Cc: "Ming-Ching Tiew" <mctiew@yahoo.com>, "tproxy@lists.balabit.hu" <tproxy@lists.balabit.hu> Date: Tuesday, September 18, 2012, 6:11 PM Hello,
AFAIK it is possible. 1. You have to bind new (spoofed) connection's port in certain range (e.g. 5000 - 10000, not ephemeral port range). 2. Setup rule to forward all outgoing TCP packets to ports in that range to localhost 3. Make connections to physical, not loopback address.
I have it running on production for about 2 months now.
Iptables rules and routes: ip rule add fwmark 1 lookup 100 ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -N DIVERT iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT iptables -t mangle -A DIVERT -j MARK --set-mark 1 iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A OUTPUT -p tcp --dport 5000:9999 -j MARK --set-mark 1
Example python code to create spoofed connection: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_IP, 19, 1) # IP_TRANSPARENT, not available in python's stdlib s.bind(('1.2.3.4', 5001)) s.connect(('192.168.1.9', 1234)) # connection always to physical interface address!
I do free port management by myself, but you can do bind() in a loop.
If the understand correctly, the only thing you added is the iptables -t mangle -A OUTPUT -p tcp --dport .....-j MARK --set-mark 1 I did exactly as what you did, however it did not seem to work for my test case. For my case, the server is a http server, so I only need to setmark on the listening http port, ie iptables -t mangle -A OUTPUT -p tcp --dport 9090 -j MARK --set-mark 1 The outgoing packets from the spoofing client (program) seem to get appear in the lo interface, however, the server reply did not get back to the spoofing client, instead the packet went out to the external interface ( confirmed using tcpdump ).
Hi, This may work, the point is that the TPROXY target will not reroute packets, so if they originally were destined to the outgoing interface, they will continue to be so and will never cause local sockets to be looked up. If the packet is already routed to localhost, then it can work. On Tue, 2012-09-18 at 20:11 +0200, Karol Piłat wrote:
Hello,
AFAIK it is possible. 1. You have to bind new (spoofed) connection's port in certain range (e.g. 5000 - 10000, not ephemeral port range). 2. Setup rule to forward all outgoing TCP packets to ports in that range to localhost 3. Make connections to physical, not loopback address.
I have it running on production for about 2 months now.
Iptables rules and routes: ip rule add fwmark 1 lookup 100 ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -N DIVERT iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT iptables -t mangle -A DIVERT -j MARK --set-mark 1 iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A OUTPUT -p tcp --dport 5000:9999 -j MARK --set-mark 1
Example python code to create spoofed connection: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_IP, 19, 1) # IP_TRANSPARENT, not available in python's stdlib s.bind(('1.2.3.4', 5001)) s.connect(('192.168.1.9', 1234)) # connection always to physical interface address!
I do free port management by myself, but you can do bind() in a loop.
Best Regards, Karol Pilat
W dniu 18.09.2012 10:04, Balazs Scheidler pisze:
Hi,
IIRC it doesn't work for local connections/sockets, as it can't reroute outgoing packets to the local interface.
On Sun, 2012-07-29 at 06:30 -0700, Ming-Ching Tiew wrote:
tproxy has problem working within 2 processes on the same machine, ie a client process using tproxy to spoof an IP, has problem communicating with the server process within the same machine.
It seems tproxy attaches itself to mangle table PREROUTING chain, that is unable to hook to the in-machine process. I figured that for it to work, in this case, it needs to be able to attach itself to the INPUT chain. However that hook is not supported.
Is there a way to get around this problem ?
-- Bazsi
participants (3)
-
Balazs Scheidler
-
Karol Piłat
-
Ming-Ching Tiew