Ignore certain ports?
Opened this issue · 6 comments
GoogleCodeExporter commented
I realise this is more of a request than a bug but I am not sure where requests
should be posted?
What I'd really like to be able to do is exclude certain ports from the system.
So for example a mail client connecting to IMAP or SMTP would bypass tun2socks
and use the default gateway.
This is fairly easy to do in Linux but Windows does not offer any sort of per
port routing.
I'm fairly sure it would be easy enough to have tun2socks detect those ports
and do something different with them in case they are part of the exclusion
list but where I'm getting stuck is the what..
Say a connection for port 25 comes in and tun2socks decides it should not send
this connection through the SOCKS as far as I can tell there is no way for it
to establish the connection as any attempt to make the connection directly will
end up right back into tun2socks due to the system routing rules?
The only way I can think of is perhaps intercepting the packets with dest port
25 from within tun2socks and forwarding them to another gateway kind of like an
ip tables packet filter in linux..
That is where I'm getting stuck as packet processing goes beyond my knowledge
of badvpn.
Is what I'm suggesting even possible?
I'm happy to look at the code if you could point me in the right direction?
Many thanks
Original issue reported on code.google.com by mike...@gmail.com
on 3 Dec 2013 at 9:36
GoogleCodeExporter commented
I've been thinking before about this, because it really would be useful. But
I've reached similar conclusions. There doesn't seem to be an easy way to
redirect connections to where they would go in the absence of tun2socks. So I
see making the OS route them to where you want the only way to go.
But that is highly platform dependent. Unfortunately, from my googling, it
doesn't seem possible on Windows, at least on the network layer. It may be
possible on the socket layer using the "Layered Service Provider" interface.
But it's fair to say it would be a great undertaking, and at least I don't have
the time or need for such a feature.
Original comment by ambr...@gmail.com
on 15 Dec 2013 at 9:26
- Changed state: WontFix
GoogleCodeExporter commented
Thanks for your reply. Actually I figured out how to do it very easily on
Windows!
It works by checking the ports on new connections and when it sees a port it
should ignore it does not connect to the SOCKS server but instead connects
directly to the destination IP and of course does not do any of the socks
initialization stuff, it just sends and receives the data directly.
The problem of course is that with routing setup the new connection will just
go straight back to tun2socks again and end up in a never ending loop. The
trick is before connecting to the destination IP/port you bind the new socket
to the main interface IP, that forces Windows to use that interface therefore
bypassing the routing table.
Because I get tun2socks to connect to a local proxy before that proxy connects
out to a remote server I do this myself locally without changing the tun2socks
code but I'm sure it can be done very easily in that code too.
So currently the code goes something like...
1) New connection received by tun2socks
2) Connect to provided socks server
3) Authenticate with socks & send dest info
4) Start tunnelling data between source and proxy
For ports to be ignored
1) New connection received by tun2socks
2) New socket created and bound to main interface IP (not TAP)
3) Socket connects to destination IP/port
4) Start tunnelling data between source and dest
Works beautifully here!
Original comment by mike...@gmail.com
on 16 Dec 2013 at 9:21
GoogleCodeExporter commented
Wow, that's wonderful. Such a nice trick!
From what I understand, you've already gotten it to work? In that case would
you mind sharing the code? If it's that easy it just may get into "official"
tun2socks distribution ;)
Original comment by ambr...@gmail.com
on 16 Dec 2013 at 9:27
- Changed state: Accepted
GoogleCodeExporter commented
Oh sorry I missed the bit about your local proxy.
Original comment by ambr...@gmail.com
on 16 Dec 2013 at 9:43
GoogleCodeExporter commented
I can yeah but as I said I made the change in my local socks code, not in
tun2socks.. I know my way around my code so I implemented the change in a few
minutes.. changing tun2socks would take me quite a bit longer!
The binding code is simple enough:
struct sockaddr_in sa_loc;
memset(&sa_loc, 0, sizeof(struct sockaddr_in));
sa_loc.sin_family = PF_INET;
sa_loc.sin_port = htons(0);
sa_loc.sin_addr.s_addr = inet_addr((const char*)localIP);
bind(handle, (struct sockaddr *)&sa_loc, sizeof(struct sockaddr));
Getting the main interface IP is a little more tricky and the way I do it has
to be done BEFORE the routing table is modified so I do it when my app starts
up.
1) GetIpForwardTable() to get the routing table
2) Look for the route with 0.0.0.0
3) Call GetIpAddrTable() and using the IFIndex from GetIpForwardTable return
the first (address) field
Sorry I don't have this as a complete code solution as I'm doing half of it in
my C++ socks code and the other have in my C# service code.
Original comment by mike...@gmail.com
on 16 Dec 2013 at 9:43
GoogleCodeExporter commented
Oh, I forgot to mention that an entry needs to exist in the routing table for
0.0.0.0 using the main interface, just with a higher metric than the route for
tun2socks
Original comment by mike...@gmail.com
on 16 Dec 2013 at 10:11